• vuex 的基本使用之Module


    Module

    首先介绍下基本的组件化规则:你可以根据项目组件的划分来拆分 store,每个模块里管理着当前组件的状态以及行为,最后将这些模块在根 store 进行组合

    const moduleA = {
        state: { ... },
        getters: { ... }
        mutations: { ... }
    };
    
    const moduleB = {
        state: { ... },
        getters: { ... },
        mutations: { ... },
        actions: { ... }
    };
    
    const store = new Vuex.Store({
        modules: {
            a: moduleA,
            b: moduleB
        }
    });
    
    console.log(store.state.a); // moduleA 的 state

    接下来看 Vuex 核心在模块化后的使用注意事项。

    请参考上文 Vuex 核心知识 (2.0)

     

    State

    在 Vuex 模块化中,state 是唯一会根据组合时模块的别名来添加层级的,后面的 getters、mutations 以及 actions 都是直接合并在 store 下。

    例如,访问模块 a 中的 state,要通过 store.state.a,访问根 store 上申明的 state,依然是通过 store.state.xxx 直接访问。

    const moduleA = {
        state: {
            maState: 'A'
        }
    };
    
    const moduleB = {
        state: {
            mbState: 'B'
        }
    };
    
    const store = new Vuex.Store({
        modules: {
            a: moduleA,
            b: moduleB
        },
        state: {
            rtState: 'Root'
        }
    });
    
    console.log(store.state.a.maState); // A
    console.log(store.state.b.mbState); // B
    console.log(store.state.rtState); // Root

     

    Getters

    与 state 不同的是,不同模块的 getters 会直接合并在 store.getters 下

    const moduleA = {
        state: {
            count: 1
        },
        getters: {
            maGetter(state, getters, rootState) {
                return state.count + rootState.b.count;
            }
        }
    };
    
    const moduleB = {
        state: {
            count: 2
        },
        getters: {
            mbGetter() {
                return 'Hello Vuex';
            }
        }
    };
    
    const store = {
        modules: {
            a: moduleA,
            b: moduleB
        }
    };
    
    console.log(store.getters.maGetter); // 3
    console.log(store.getters.mbGetter); // Hello Vuex

    在上文我们介绍过 getters 的回调函数所接收的前两个参数,模块化后需要用到第三个参数——rootState。参数: 1. state,模块中的 state 仅为模块自身中的 state;2. getters,等同于 store.getters;3. rootState,全局 state。

    通过 rootState,模块中的 getters 就可以引用别的模块中的 state 了,十分方便。

    注意:由于 getters 不区分模块,所以不同模块中的 getters 如果重名,Vuex 会报出 'duplicate getter key: [重复的getter名]' 错误。

     

    Mutations

    mutations 与 getters 类似,不同模块的 mutation 均可以通过 store.commit 直接触发。

    const moduleA = {
        state: {
            count: 1
        },
        mutations: {
            sayCountA(state) {
                console.log('Module A count: ', state.count);
            }
        }
    };
    
    const moduleB = {
        state: {
            count: 2
        },
        mutations: {
            sayCountB(state) {
                console.log('Module B count: ', state.count);
            }
        }
    };
    
    const store = {
        modules: {
            a: moduleA,
            b: moduleB
        }
    };
    
    store.commit('sayCountA'); // Module A count: 1
    store.commit('sayCountB'); // Module B count: 2 

    mutation 的回调函数中接收唯一的参数——当前模块的 state。如果不同模块中有同名的 mutation,Vuex 不会报错,通过 store.commit 调用,会依次触发所有同名 mutation。

     (注意:唯一的参数位置是指非payload参数位置)

    Actions

    与 mutations 类似,不同模块的 actions 均可以通过 store.dispatch 直接触发。

    const moduleA = {
        state: {
            count: 1
        },
        mutations: {
            sayCountA(state) {
                console.log('Module A count: ', state.count);
            }
        },
        actions: {
            maAction(context) {
                context.dispatch('mbAction');
            }
        }
    };
    
    const moduleB = {
        state: {
            count: 2
        },
        mutations: {
            sayCountB(state, num) {
                console.log('Module B count: ', state.count+num);
            }
        },
        action: {
            mbAction({ commit, rootState }) {
                commit('sayCountA');
                commit('sayCountB', rootState.a.count);
            }
        }
    };
    
    const store = {
        modules: {
            a: moduleA,
            b: moduleB
        }
    };
    
    store.dispatch('maAction'); // Module A count: 1、Module B count: 3

    从上例可以看出,action 的回调函数接收一个 context 上下文参数,context 包含:1. state、2. rootState、3. getters、4.rootGetters,5. commit、6. dispatch 属性,为了简便可以在参数中解构{ dispatch, commit, state}。

    在 action 中可以通过 context.commit 跨模块调用 mutation,同时一个模块的 action 也可以调用其他模块的 action。

    同样的,当不同模块中有同名 action 时,通过 store.dispatch 调用,会依次触发所有同名 actions。 

    在定义了namedspaced为true后,若需要在全局命名空间内dispatch  action 或commit mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。
    modules:{
      foo:{
        namedspace:true,
        actions: {
          someAction ({ dispatch, commit, getters, rootGetters }) {
            getters.someGetter // -> 'foo/someGetter'
            rootGetters.someGetter // -> 'someGetter'
            dispatch('someOtherAction') // -> 'foo/someOtherAction'
            dispatch('someRootAction', null, { root: true }) // -> 'someRootAction'
            commit('someMutation') // -> 'foo/someMutation'
            commit('someRootMutation', null, { root: true }) // -> 'someRootMutation'
          },
          someOtherAction (ctx, payload) { ... }

      }
    }

    最后有一点要注意的是,将 store 中的 state 绑定到 Vue 组件中的 computed 计算属性后,对 state 进行更改需要通过 mutation 或者 action,在 Vue 组件中直接进行赋值 (this.myState = 'ABC') 是不会生效的。

    参考 https://vuex.vuejs.org/zh-cn/modules.html 理解

     

  • 相关阅读:
    为什么说LD_LIBRARY_PATH不好
    linux c/c++ code统计耗时
    c++: abs() 与fabs() 的区别
    char代表有符号还是无符号?
    git三个小技巧:删除指定 commit、修改历史 commit 中的作者信息、合并某文件到当前分支
    vim选中字符复制/剪切/粘贴
    git rebase
    git打patch
    数据仓库生命周期工作箱 第六章 维度建模
    数据仓库生命周期工作箱 第二章 项目/项目群的启动与管理
  • 原文地址:https://www.cnblogs.com/FineDay/p/8897700.html
Copyright © 2020-2023  润新知