前言
工作中经常会用到类似于 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>