Vuex管理dialog、toast等常见全局性组件状态时唯一性的问题
前言
工作中经常会用到类似于 dialog
、toast
、popover
等一些状态提示组件。对于这种全局性的组件,通常会用到 vuex
来管理组件的信息。这样的好处是代码维护起来更加友好,但是也需要考虑唯一性的问题。
场景
以 dialog
为例,唯一性问题是指当页面中有多处内容调用了同一个事件,而这个事件都是修改了全局的 vuex
状态,从而导致页面中多次依赖于全局状态的组件会同时展示。例如以下场景:
要解决这样的问题,需要在 state
中设置一个 id
变量,同时给组件调用的时候传一个 id
,在展示组件之前判断两个 id
是否一致,一致才展示。
代码
store.js
const state = {
id: "", // 用于判断唯一性
isShow: false,
};
const mutations = {
setShowDialog(state, data) {
state.id = data.id;
state.isShow = true;
},
};
export default {
namespaced: true, // 解决命名冲突(使用时需要备注模块名)
state,
mutations,
};
dialog.vue
<!-- 全局dialog组件 -->
<template>
<div v-if="isShowCurrentDialog">
<!-- 组件逻辑省略 -->
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
props: {
currId: {
type: String,
default: "",
},
},
computed: {
...mapState(["id"]),
isShowCurrentDialog() {
if (this.currId) {
return this.id === this.currId ? this.isShow : false;
} else {
return this.isShow;
}
},
},
};
</script>
xxx.vue
<!-- 调用dialog的组件 -->
<template>
<div>
<ul>
<!-- 模拟同时多个dialog调用场景 -->
<li v-for="item in listData" :key="item.name" @click="setShowDialog({ id: item.name })">
<Dialog :id="item.name" />
</li>
</ul>
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
data() {
return {
listData: [
{
name: "aaa",
},
{
name: "bbb",
},
{
name: "ccc",
},
],
};
},
methods: {
...mapMutations(["setShowDialog"]),
},
};
</script>
以上内容为个人的工作经验理解,能力有限可能不是最佳方案,今后如有更好的思路我会对随笔内容编辑优化。