module 的用法
一开始以为模块只能是一层,仔细看了官网才发现,原来模块还可以有n层,即子模块、子子模块、子子子模块无穷匮也。而且还可以动态注册模块。这是要疯的节奏呀。
我还是感觉模块应该扁平化设计,最多两层,多了就容易乱套,理解起来也费劲。
定义模块
const user = {
// namespaced: true, // 避免重名
state: () => ({
userInfo: {
userId: 123,
userCode: '',
userNick: ''
},
userRole: []
}),
mutations: {
setUser(state, code) {
state.userInfo.userCode = code
}
},
getters: {
getUser(state) {
return state.userInfo
}
},
actions: {
// { state, commit, rootState }
setUsera (store, code) {
store.commit('setUser', code)
}
}
}
export default user
state
这里有点变化,需要用返回函数的方式,原因和组件里的data的原因类似。这样也就意味着一个模块可以被多次加载进来。
- 访问方式
const userInfo = store.state.user.userInfo
getter
简单的说,没啥变化,传递进来的state只包含自己模块的state。
- 访问方式
const userInfo2 = store.getters.getUser
031getter的state参数.png
mutations
简单的说,也是没啥变化,传递进来的state只包含自己模块的state,另一个参数是组件调用时传递进来的参数。
- 访问方式
store.commit('setUser', '要修改的数据')
030setter的state参数.png
action
简单的说呢,也是只需要操作自己的模块的就行。
-
store
这个参数是一个比较复杂的对象,全部成员如下图,一般可以用结构的方式获取需要的参数,比如这样:{ state, commit, rootState }。
020action的参数store0.png
参数详细内容:
020action的参数store.png
可以依据这些内容实现各种功能。
020action的参数store2.png-
code
第二个大参数,就是组件调用的时候传递过来的参数。 -
访问方式
store.dispatch('setUsera', '要修改的数据')
加载模块到store
模块代码写好了,如何加入进来呢?其实很方便,可以直接写,也可以挂个别名。
export default Vuex.createStore({
state: {
count: 0,
myObject: {
time: '现在的时间:'
},
myArray: [1,2,2,3,4]
},
getters: {},
mutations: {},
actions: {},
modules: {
// 注意:这个myObject会覆盖掉根的myObject。
// 设置命名空间也没有用,还是会覆盖。
// 所以要避免重名。
myObject: user,
user: user,
person: user
}
})
命名空间
- namespaced: true
简单的说,这个是避免命名重复的问题的。
我们可以把user模块加载三次来看看区别。
不加命名空间
- state
模块的导入名称会和根的 根state的成员 并列,如果重名的话,根的state成员会被覆盖掉。
比如这里根state的成员myObject,就被覆盖掉了。
蓝色框是根的state的成员。
红色框是被覆盖的。
橙色框是两个模块。
-
mutations
会变成数组形式,每个模块的同名都会被调用。
001没有命名空间的setter.png -
action
也会变成数组的形式,每个模块的同名action都会被调用
002没有命名空间的action.png
-
getter
只会保留一个,另外两个会报错。
004没有命名空间的getter的报错.png
加上命名空间
state不受影响,其他都会加上“路径”作为区分。
-
state
还是那个样子,没有变化。 -
mutations
由斜线分隔组成的路径,这样可以明确区分是哪个模块的函数,不会弄错。
访问方式:
store.commit('user/setUser', 'user的code')
store.commit('myObject/setUser', 'myObject的code')
store.commit('person/setUser', 'person的code')
可以分别给每个模块的state设置内容,那么其实就是一个模块。
006有命名空间的setter.png- action
也是由斜线区分。
访问方式:
store.dispatch('user/setUsera', 'action的user的code')
008有命名空间的action.png
- getter
也是用斜线分隔开。
访问方式:
store.getters['user/getUser']
因为有斜线,所以需要用字符串的方式来访问。
009有命名空间的getter.png官网还有更牛叉的功能,我先不说了,头有点疼……
在线演示:
https://naturefwvue.github.io/nf-vue-cnd/cnd/project-vuex/
源码:
https://github.com/naturefwvue/nf-vue-cnd/tree/main/cnd/project-vuex
网友评论