当我们使用 Vuex 实现全局状态维护时,可能需要将状态值划分多个模块,比如一些 root 级的用户登录状态,token,用户级的用户信息,购物车级的购物车信息。

下面我们实例演示下如何在多模块下使用 mapState/mapMutations。

  • modules 只作用于属性,属性会归属在相应的模块名的命名空间下。
  • mutations, actions, getter 没有命名空间的限定,所以要保证全局的唯一性,否则后者会覆盖前者

store/index.js

import Vue from 'vue'import Vuex from 'vuex'import user from './user'import order from './order'Vue.use(Vuex)const store = new Vuex.Store({    modules: {        user,        order    },    state: {        hasLogin: false,        token: ""    },    mutations: {        setHasLogin(state, hasLogin) {            state.hasLogin = hasLogin        },        setToken(state, token) {            state.token = token        }    }})export default store

store/user.js

const state = {    name: "sqrtcat",    age: 25}const mutations = {    setUserName(state, name) {        state.name = name    },    setUserAge(state, age) {        state.age = age    }}const actions = {}const getters = {}export default {    state,    mutations,    actions,    getters}

store/order.js

const state = {    name: "cart",    count: 0}const mutations = {    setOrderName(state, name) {        state.name = name    },    setOrderCount(state, count) {        state.count = count    }}const actions = {}const getters = {}export default {    state,    mutations,    actions,    getters}

Vue 引入

import Vue from 'vue'import App from './App'import store from './store'Vue.config.productionTip = falseVue.prototype.$store = store // 注入仓库const app = new Vue({    store// 注入仓库})app.$mount()

index.vue

<template>    <view>        <button class="primary" @click="setUserName('big_cat')">setUserName</button>        <button class="primary" @click="setUserAge(27)">setUserAge</button>        <button class="primary" @click="setOrderName('yes')">setOrderName</button>        <button class="primary" @click="setHasLogin(true)">setHasLogin</button>        <button class="primary" @click="setToken('tokentokentokentoken')">setToken</button>        <view class="">            {{userName}}        </view>        <view>{{userAge}}</view>        <view>{{orderName}}</view>        <view>{{hasLogin}}</view>        <view>{{token}}</view>    </view></template><script>    import {        mapState,        mapMutations    } from "vuex"    export default {        data() {            return {}        },        computed: {            // 原生            hasLogin() {                return this.$store.state.hasLogin            },            token() {                return this.$store.state.token            }            // 仓库root属性 可以直接 magic 赋值            // ...mapState(["hasLogin", "token"]),            // 因为 modules 下的属性使用了命名空间 所以不能使用数组方式的 magic            ...mapState({                userName: state => state.user.name,                userAge: state => state.user.age,                orderName: state => state.order.name            }),            // 更多示例            ...mapState({                hasLogin(state) {                    return state.hasLogin                },                token(state) {                    return state.token                }            }),            ...mapState({                hasLogin: (state) => {                    return state.hasLogin                },                token: (state) => {                    return state.token                }            }),        },        methods: {            // vuex 在使用了 modules 模式时            // mutation依然没有命名空间的概念 所以在定义 mutations 时要注意全局的唯一性            // 否则后者会覆盖前者            ...mapMutations(["setHasLogin", "setToken"]),            // magic style1            ...mapMutations(["setUserName", "setUserAge", "setOrderName"]),            // magic style2            ...mapMutations({                setUserName(commit, userName) {                    commit("setUserName", userName)                },                setUserAge(commit, userAge) {                    commit("setUserAge", userAge)                },                setOrderName(commit, orderName) {                    commit("setOrderName", orderName)                }            }),            // 原生写法            setUserName(userName) {                this.$store.commit("setUserName", userName)            },            setUserAge(userAge) {                this.$store.commit("setUserAge", userAge)            },            setOrderName(orderName) {                this.$store.commit("setOrderName", orderName)            }        }    }</script>