mapState
輔助函數
當一個組件需要獲取多個狀態的時候,將這些狀態都聲明為計算屬性會有些重復和冗余。為了解決這個問題,我們可以使用 mapState
輔助函數幫助我們生成計算屬性,讓你少按幾次鍵:
// store.js /** vuex的核心管理對象模塊:store */ import Vue from 'vue'; import Vuex from 'vuex'; import vuexTest from './modules/vuexTest'; Vue.use(Vuex) // 狀態對象 const state = { // 初始化狀態 這里放置的狀態可以被多個組件共享 count: 1, count1: 1, count2: 2, count3: 3, name: 'daming' }; const mutations = {}; const actions = {}; const getters = {}; export default new Vuex.Store({ state, // 狀態 mutations, // 包含多個更新state函數的對象 actions, // 包含多個隊形事件回調函數的對象 getters, // 包含多個getter計算屬性函數的對象 modules: { // 模塊化 vuexTest } });
1、在界面或組件中不使用mapState獲取vuex中state的狀態
雖然將所有的狀態放入Vuex,會使狀態變化更顯式和易調試,但也會使代碼變得冗長和不直觀。如果有些狀態嚴格屬於單個組件,最好還是作為組件的局部狀態,比如temp變量,hello, number作為組件的局部狀態。
<!-- test.vue --> <template> <div id="example"> {{count}} {{name}} {{helloName}} {{addNumber}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, } }, computed: { // 由於 Vuex 的狀態存儲是響應式的,所以可以使用計算屬性來獲得某個狀態 // 通過下面的計算屬性,就可以在當前組件中訪問到count,name,helloName,addNumber 在模板中我們通過大括號符號打印出來,當然這些可以在vue中使用,比如在watch中監聽,在mounted中使用 // 下面的計算屬性涉及到了vuex管理的狀態 count() { // 這實際上是ES6中對象的簡化寫法 完整寫法是 count: function { return this.$store.state.count } return this.$store.state.count }, name() { // 這實際上是ES6中對象的簡化寫法 完整寫法是 name: function { return this.$store.state.count } return this.$store.state.count }, helloName: function (state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.hello + this.$store.state.name }, addNumber: function (state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.number + this.$store.state.count } // 但有一個問題 // 當一個組件需要獲取多個狀態的時候,將這些狀態都聲明為計算屬性會有些重復和冗余。比如上面的name(),count(),helloName(),顯得重復,代碼冗長 // 為了解決這個問題,我們可以使用 mapState 輔助函數幫助我們生成計算屬性,讓你少按幾次鍵: }, watch: { helloName(newVal,oldVal){ console.log(newVal); console.log(oldVal); } }, mounted(){ console.log(this.helloName); } } </script>
2、在組件、界面中使用mapState獲取vuex中state的數據
<!-- test.vue --> <template> <div id="example"> {{count}} {{count1}} {{repeatCount}} {{count3}} {{name}} {{helloName}} {{addNumber}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, count2: 2 } }, computed: { /** * 數組形式 * 當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給 mapState 傳一個字符串數組。 * */ ...mapState(["count", "name"]), /** * 對象形式 */ ...mapState({ count, // 這種就是count:"count", 的簡寫 count1: "count1", repeatCount: "count2", // 當組件中與vuex中的字符已經出現重復時,使用 repeatCount 來映射 store.state.count2 count3: (state) => { // 映射 count3 為 store.state.conut3的值 return state.count3 }, helloName: function (state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.hello + state.name }, addNumber: function (state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.number + state.count } }) }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.helloName); } } </script>
3、modules的vuexTest模塊中state數據
/** * vuexTest.js * modules 中的數據 */ export default { namespaced: true, state: { moduleVal: 1, moduleName: "戰戰兢兢" }, getters: { }, mutations: { }, actions: { } }
4、在界面或組件中不使用mapState獲取模塊modules vuexTest中state的狀態
<!-- module test.vue --> <template> <div id="example"> {{moduleVal}} {{moduleName}} {{moduleNameOther}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, } }, computed: { moduleVal(){ return this.$store.state.vuexTest.moduleVal }, moduleName(){ return this.$store.state.vuexTest.moduleVal }, moduleNameOther(){ // 當組件中與vuex中的字符已經出現重復時,使用 moduleNameOther 來映射 store.state.vuexTest.moduleName return this.$store.state.vuexTest.moduleVal }, }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.addNumber); } } </script>
5、在界面或組件中使用mapState獲取模塊modules vuexTest中state的狀態
<!-- module test.vue --> <template> <div id="example"> {{moduleVal}} {{moduleName}} {{moduleNameOther}} </div> </template> <script> import { mapState } from 'vuex' export default { data() { return { hello: 'hello', number: 1, } }, computed: { /** * 數組形式 * 當映射的計算屬性的名稱與 與模塊中vuexTest中state 的子節點名稱相同時,我們也可以給 mapState 傳一個字符串數組, * */ ...mapState("vuexTest", ["moduleVal", "moduleName"]), // "vuexTest" 指向模塊vuexTest,"moduleVal"表示store.vuexTest.moduleVal /** * 對象形式 */ // 第一種對象方式 ...mapState({ moduleVal: "vuexTest/moduleVal", moduleNameOther: "vuexTest/moduleName" // 表示 moduleNameOther 映射到vuexTest模塊中moduleName }), ...mapState("vuexTest", { moduleVal, // 這種就是moduleVal:"moduleVal", 的簡寫 moduleName: "moduleName", moduleNameOther: "moduleName", // 當組件中與vuex中的字符已經出現重復時,使用 moduleNameOther 來映射 store.state.vuexTest.moduleName moduleVal: (state) => { // 映射 moduleVal 為 store.state.vuexTest.moduleVal的值 return state.moduleVal }, helloName: function (state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.hello + state.moduleName }, addNumber(state) { // 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數,不能使用箭頭函數 return this.number + state.moduleVal } }) }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.addNumber); } } </script>