六、Vuex - Module

Module 模块

Vuex 允许将 store 分割成模块(module), 每个模块拥有自己的state、mutation、action、getter甚至是嵌套子模块, 从上至下进行同样方式的分割。分割的好处是让代码更加清晰, 易于维护管理.

模块划分及访问

// A 模块
const moduleA = {
    state: {},
    getters: {},
    mutations: {},
    actions: {}
}

// B 模块
const moduleB = {
    state: {},
    getters: {},
    mutations: {},
    actions: {}
}

const store = new Vuex.Store({
    modules: {
        a: moduleA,
        b: moduleB
    }
});

// 访问独立模块的状态
store.state.a // 访问 moduleA 的状态
store.state.b // 访问 moduleB 的状态

模块的局部状态

  • 模块内部的 mutation、getter 的第一个参数为模块的局部状态对象
  • 模块内部的 action中, 局部状态通过 context.state 暴露, 根节点点状则为 content.rootState
  • 模块内部的 getter, 根节点的状态会作为第三个参数暴露出来
const moduleA = {
    getters: {
        getCount (state, getters, rootState) {
            // state 局部状态
            // 局部 getters,
            // rootState 根节点状态
            return state.count + rootState.count;
        }
    },
    mutations: {
        increment (state) {
            state.count++;
            // state 模块的局部状态
        }
    },
    actions: {
        increment ({ state, commit, rootState }) {
            // state 局部状态
            // rootState 根节点状态
            commit('increment');
        }
    }
}

命名空间

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

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

const store = new Vuex.Store({
    modules: {
        account: {
            namespaced: true,

            // 模块内容
            sstate: {},
            getters: {
                inAdmin () {} // getters['account/isAdmin']
            },
            mutations: {
                login () {} // commit('account/login')
            },
            actions: {
                login () {} // dispatch('account/login')
            },

            // 嵌套模块
            modules: {
                // 继承父模块的命名空间
                myPage: {
                    state: {},
                    getters: {
                        profile () {} // getter['account/profile']
                    }
                },
                // 进一步嵌套命名空间
                posts: {
                    namespaced: true,
                    state: {},
                    getters: {
                        popular () {} // getter['account/posts/popular']
                    }
                }
            }
        }
    }
});

在带命名空间的模块内访问全局内容

  • 使用全局的 state 和 getter, rootState 和 rootGetters 会作为第三和第四参数传入 getter, 也会通过 context 对象的属性传入action
  • 分发和提交全局命名空间的action、mutation, 将 { root: true } 作为第三参数传给 dispatch 或 commit 即可
modules: {
    foo: {
        namespaed: true,
        getters: {
            someGetter (state, getters, rootState, rootGetters) {
                getters.someOther // 'foo/someOther'
                rootGetters.someOhter // 'someOther'
            }
        },
        actions: {
            someAction ({ dispatch, commit, getters, rootGetters }) {
                dispatch('someOtherAction') // 'foo/someOhterAction'
                dispatch('someOtherAction', null, { root: true }) // 'someOhterAction' 派发根节点的 action

                commit('someMutation') // 'foo/someMutation'
                commit('someMutation', null, { root: true }) // 'someMutation' 提交根节点的 mutation
            }
        }
    }
}

在命名空间模块中注册全局 action

action: {
    someAction: {
        root: true, // 将注册到全局中
        handler () {}
    }
}

带命名空间的模块如何使用

当使用 mapState、mapGetters、mapActions、mapMutations时需要注意

// 方式一: 统一编写
computed: {
    ...mapState({
        a: state => state.some.nested.module.a,
        b: state => state.some.nested.module.b
    })
},
methods: {
    ...mapActions([
        // this['some/nested/module/foo']()
        'some/nested/module/foo',
        'some/nested/module/bar'
    ])
}

// 方式二: 将模块的空间名称作为第一个参数,自动绑定模块上下文
computed: {
    ...mapState('some/nested/module', {
        a: state => state.a,
        b: state => state.b
    })
},
methods: {
    ...mapActions('some/nested/module', {
        'foo', // this.foo()
        'bar'  // this.bar()
    })
}

// 方式三: 通过 createNamespacedHelpers 创建基于某个命名空间辅助函数
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapAction } = createNamespacedHelpers('some/nested/module');

export default {
    computed: {
        ...mapState({
            a: state => state.a,
            b: state => state.b
        })
    },
    methods: {
        ...mapActions([
            'foo',
            'bar'
        ])
    }
}

原文地址:https://www.cnblogs.com/yuxi2018/p/11966812.html

时间: 2024-10-21 09:24:34

六、Vuex - Module的相关文章

uni-app 使用vuex(vuex module)

1:uni-app 集成了vuex 直接在根目录下创建store文件夹 新建store.js import Vue from 'vue'import Vuex from 'vuex'import ‘模块名称’ from '模块路径'; Vue.use(Vuex); const $store = new Vuex.Store({ modules: { ‘引入的模块名称’, }});export default $store; 2:在main.js中引入挂载store import store  f

【转】vue技术分享-你可能不知道的7个秘密

一.善用watch的immediate属性 这一点我在项目中也是这么写的.例如有请求需要再也没初始化的时候就执行一次,然后监听他的变化,很多人这么写: created(){ this.fetchPostList() }, watch: { searchInputValue(){ this.fetchPostList() } } 上面的这种写法我们可以完全如下写: watch: { searchInputValue:{ handler: 'fetchPostList', immediate: tr

vue技术分享之你可能不知道的7个秘密

本文是vue源码贡献值Chris Fritz在公共场合的一场分享,觉得分享里面有不少东西值得借鉴,虽然有些内容我在工作中也是这么做的,还是把大神的ppt在这里翻译一下,希望给朋友带来一些帮助. 一.善用watch的immediate属性 这一点我在项目中也是这么写的.例如有请求需要再也没初始化的时候就执行一次,然后监听他的变化,很多人这么写: created(){ this.fetchPostList() }, watch: { searchInputValue(){ this.fetchPos

ES6(简介及常用)-下

八.Iterator 和 for of 值遍历(谷歌浏览器无) 1.Iterator(遍历器)的概念 JavaScript 原有的表示"集合"的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set.这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象.这样就需要一种统一的接口机制,来处理所有不同的数据结构.遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的

【转】大型Vuex项目 ,使用module后, 如何调用其他模块的 属性值和方法

Vuex 允许我们把 store 分 module(模块).每一个模块包含各自的状态.mutation.action 和 getter. 那么问题来了, 模块化+命名空间之后, 数据都是相对独立的, 如果想在模块 A 调用 模块 B 的state, actions, mutations, getters, 该肿么办? 假设有这么两个模块: 模块A: import api from '~api' const state = { vip: {}, } const actions = { async

vuex中module的命名空间概念

vuex中module的命名空间概念 默认情况下,模块内部的 action.mutation 和 getter 是注册在全局命名空间的. 弊端1:不同模块中有相同命名的mutations.actions时,不同模块对同一 mutation 或 action 作出响应. 弊端2:当一个项目中store分了很多模块的时候,在使用辅助函数mapState.mapGetters.mapMutations.mapActions时,很难查询,引用的state.getters.mutations.action

(十六)硅谷外卖-使用 vuex 管理状态

一.下载vuex npm install --save vuex 二.定义state store/state.js export default { latitude: 40.10038, // 纬度 longitude: 116.36867, // 经度 address: {}, // 地址信息对象 categorys: [], // 分类数组 shops: [], } 三.定义mutation-types store/mutation-types.js export const RECEIV

[Vuex系列] - Module的用法(终篇)

于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿.为了解决以上问题,Vuex 允许我们将 store 分割成模块(module).每个模块拥有自己的state.mutation.action.getter.甚至是嵌套子模块——从上至下进行同样方式的分割: 如何使用module 在store文件夹下新建modules文件夹,并在下面建立moduleA.js和moduleB.js文件用来存放vuex的modules模块 module

vuex之module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿. 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module).每个模块拥有自己的 state.mutation.action.getter.甚至是嵌套子模块——从上至下进行同样方式的分割: 在src下建立文件夹store,用于存放各个模块以及根级别的文件 在index.js文件中导出store import Vue from 'vue' import Vue