vuex的模块化之间数据交互与命名空间的使用

namespaced 命名空间

引用两位大佬的解释

1、默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的,这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性。

2、vuex中的store分模块管理,需要在store的index.js中引入各个模块,为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名

举个例子

类似于发布订阅机制,多个模块的同名方法会放在同一个数组中,在对根store进行dispatch、commit抛发事件时,会执行这一个事件对应数组里的所有函数,也就是所有的模块都会执行同名函数,有时候想要针对某个模块进行事件的抛发,这个时候为每个同名方法添加模块的前缀就能解决这个问题了

namespaced:true 就会自动的在方法名前面添加模块名来进行方法区分

const state = {  //创建状态存储
    name:"product",
}

const mutations = {  //创建状态修改函数
    setName(store) {
        store.name="product更改"
    }
}

export default {  //导出store模块配置
	namespaced: true, //为模块添加命名空间,这样在外部可以根据map来映射模块方法属性
    state,
    mutations
}

组件中map引用

methods: { // 通过methods来获取模块的mutitions与actions
   ...mapMutations('product',['setName'])  // 为setName上追加/product,最终查找的是 /product/setName方法
},

这个方法在模块设置了namespaced: true后就已经在根store的_mutations中进行了重命名为/product/setName ,所以可以正确的查找到

原理

namespaced: true;

模块在导出时加上这个属性开启了命名空间,这样这个模块的所有方法都会在前面加上模块名前缀,同时在模块进行commit、dispatch操作来抛发事件也会在前面补上模块前缀,如

文件名product.js

const state = {
    name: "product",
}
const mutations = {
    setName(store) {  //在全局引入后方法名为  'product/setName'
        store.name = "product更改";
        console.log("produtaaa")
    }
}

const actions = {
    subNameToStudy({ commit }, payLoad) {  //在全局引入后方法名为  'product/subNameToStudy'
        commit("study/setName", "新名字", {  //在进行提交时类型为  'product/study/setName'
            root: true
        });

		commit("setName", "新名字", {  //在进行提交时类型为  'product/setName'
            root: true
        });
    }
}

export default {
    state,
    mutations,
    actions,
    namespaced: true
}

模块在根模块进行引入后就合并在了根模块的方法集中(_mutations、_actions),这样进行commit、dispatch时也是在向根模块进行事件的提交与抛发

由此可以看到,在设置namespaced: true后的模块无论进行什么操作都会去查找自身模块中的方法,在commit提交product/setName事件,而导出时的setName事件正好变为product/setName这样完美的进行了事件在本模块的抛发并且不会影响其他模块

通过命名空间与actions来进行store模块之间的事件抛发

有这样的一种情况,在两个独立的模块中要进行某些数据的交互,需要进行事件的抛发但是设置命名空间后再actions进行commit与dispatch时会自动在前面添加当前模块的前缀,强制模块向自身抛发事件,做不到向另一个具有命名空间的模块进行抛发,这时候要想办法在抛发时将命名空间的自动添加前缀去掉

在actions方法的commit与dispatch方法中第三个参数具有阻止添加前缀的功能{root:true},他的意思是向根模块进行抛发,既然不是向本模块抛发命名空间会判定不加前缀

抛发事件的store模块(projuct.js)

const actions = {
    subNameToStudy({ commit }, payLoad) {
        commit("study/setName", "新名字", { //由于添加了root:true ,在进行commit与dispatch时不再添加'projuct/'前缀
            root: true
        })
    }
}

export default {
    state,
    mutations,
    actions,
    namespaced: true,
}

subNameToStudy方法中的commit向根模块抛发了一个 study/setName 事件,顾名思义我们希望找到的是具有命名空间的study模块中的setName方法

接收事件的store模块(study.js)

const state = {
    name:"study",
    age:0
}
const mutations = {
    setName({name},payLoad) {  //在进行跟模块引入时放在变为 study/setName方法名,存储在根模块的_mutations中
        name="study更改";
        console.log(payLoad,"aa")
    },
    setAge({age}){
        age=20
    }
}

export default {
    state,
    mutations,
    namespaced: true
}

在subNameToStudy抛发事件后study模块接受到了study/setName执行了setName方法 最终打印 ‘新名字 aa’

store模块间的数据交互就完成了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值