Vuex4.x(五)模块管理(上)

作者: 自然框架 | 来源:发表于2021-02-15 14:03 被阅读0次

    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的成员。
      红色框是被覆盖的。
      橙色框是两个模块。
    005没有命名空间的state.png
    • 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

    相关文章

      网友评论

        本文标题:Vuex4.x(五)模块管理(上)

        本文链接:https://www.haomeiwen.com/subject/bjnhxltx.html