Vuex modules 模式下 mapState/mapMutations 的操作實例

當我們使用 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 = false

Vue.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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章