Vuex快速入门之 模块化开发(三)

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。下面介绍两种模块化开发方式:

参考文档:https://vuex.vuejs.org/zh-cn/modules.html

Module

Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

例如,store 文件下 有 index.js, a.js, b.js

a.js

const moduleA = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
}
export default moduleA

b.js

const moduleB = {
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
}
export default moduleB

index.js

import moduleA from './a.js'
import moduleB from './b.js'
const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

命名空间方式

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为命名空间模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

例如,还是store 文件下 有 index.js, a.js, b.js

a.js

const moduleA = {
    namespaced: true,
    state: { 
        name:'lyc',
        aget: '20'
    },
    mutations: { 
        name: (state, name) => state.name = name,
        age: (state, age) => state.age = age,
    },
    actions: {
        rename(context, name){
            context.commit('name', name)
        },
        renage(context, age){
            context.commit('age', age)
        }
    },
    getters: { ... }
}
export default moduleA

b.js

const moduleB = {
    namespaced: true,
    state: { 
        type:'xxx',
    },
    mutations: {
        type: (state, type) => state.type = type,
    },
    actions: { ... },
    getters: { ... }
}
export default moduleB

index.js

import moduleA from './a.js'
import moduleB from './b.js'
const store = new Vuex.Store({
    modules: {
        moduleA: moduleA,
        moduleB: moduleB
    }
})

带命名空间的绑定函数

当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定命名空间模块时,写起来可能比较繁琐: methods: { test1(){ this.$store.dispatch(‘rename’, ‘LYC’) }, test2(){ this.$store.dispatch(‘reage’, ‘3’) } }, computed: { …mapState({ name: state => state.moduleA.name, age: state => state.moduleA.age, type: state => state.moduleB.type, }) },

对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为: methods: { …mapActions(‘moduleA’,[‘rename’,’reage’]), test1(){ this.rename(‘LYC’) }, test2(){ this.reage(‘3’) } }, computed: { …mapState(‘moduleA’,[‘name’,’age’]), …mapState(‘moduleB’,[‘type’]), },

而且,你可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('moduleA')

export default {
    computed: {
        // 在 `moduleA` 中查找
        ...mapState(['name','age'])
    }
}

其他辅助函数同 ...mapState

参考案例:我的仓库

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦