vuex是什麼? vuex是管理應用程式狀態,實現組件間通信的。 為什麼使用vuex? 在開發大型應用的項目時,會出現多個視圖組件依賴一個同一個狀態,來自不同視圖的行為需要變更同一個狀態。 在遇到以上問題,就要用到vuex,他能把組件的共用狀態抽取出來,當做一個全局單例模式進行管理,不管在何處改變狀 ...
vuex是什麼?
vuex是管理應用程式狀態,實現組件間通信的。
為什麼使用vuex?
在開發大型應用的項目時,會出現多個視圖組件依賴一個同一個狀態,來自不同視圖的行為需要變更同一個狀態。
在遇到以上問題,就要用到vuex,他能把組件的共用狀態抽取出來,當做一個全局單例模式進行管理,不管在何處改變狀態,都會通知使用該狀態的組件作出相應的修改。
最簡單的vuex實例
1 import Vue from 'vue'; 2 import Vuex form 'vuex'; 3 4 Vue.use(Vuex); 5 6 const store = new Vuex.Store({ 7 state: { 8 count: 0 9 }, 10 mutations: { 11 increment (state) { 12 state.count++ 13 } 14 } 15 })
以上就是一個簡單的vuex實例,每一個vuex應用就是一個store,在store中包含組件中的共用狀態state和改變狀態的方法mutations。
需要註意的是只能通過mutations
改變store的state
的狀態,不能通過store.state.count = 5;
直接更改,state
相當於對外的只讀屬性。
使用store.commit
方法觸發mutations
改變state
:
1 store.commit('increment'); 2 3 console.log(store.state.count) //
在Vue組件中使用vuex
如果希望Vuex狀態更新,相應的Vue組件也得到更新,最簡單的方法就是在Vue的computed
(計算屬性)獲取state
// Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count; } } }
上面的例子是直接操作全局狀態store.state.count
,那麼每個使用該Vuex的組件都要引入。為瞭解決這個,Vuex通過store
選項,提供了一種機制將狀態從根組件註入到每一個子組件中。
1 // 根組件 2 import Vue from 'vue'; 3 import Vuex form 'vuex'; 4 5 Vue.use(Vuex); 6 const app = new Vue({ 7 el: '#app', 8 store, 9 components: { 10 Counter 11 }, 12 template: ` 13 <div class="app"> 14 <counter></counter> 15 </div> 16 ` 17 })
通過這種註入機制,就能在子組件Counter
通過this.$store
訪問:
1 // Counter 組件 2 const Counter = { 3 template: `<div>{{ count }}</div>`, 4 computed: { 5 count () { 6 return this.$store.state.count 7 } 8 } 9 }
mapState函數
1 computed: { 2 count () { 3 return this.$store.state.count 4 } 5 }
這樣通過count
計算屬性獲取同名state.count
屬性,是不是顯得太重覆了,我們可以使用mapState
函數簡化這個過程。
1 import { mapState } from 'vuex'; 2 3 export default { 4 computed: mapState ({ 5 count: state => state.count, 6 countAlias: 'count', // 別名 `count` 等價於 state => state.count 7 }) 8 }
簡便方法為:
computed: mapState([ // 映射 this.count 為 store.state.count 'count' ])
Getters對象:
如果我們需要對state
對象進行做處理計算,如下:
1 computed: { 2 3 doneTodosCount () { 4 5 return this.$store.state.todos.filter(todo => todo.done).length 6 7 } 8 9 }
如果多個組件都要進行這樣的處理,那麼就要在多個組件中複製該函數。這樣是很沒有效率的事情,當這個處理過程更改了,還有在多個組件中進行同樣的更改,這就更加不易於維護。
Vuex中getters
對象,可以方便我們在store
中做集中的處理。Getters接受state
作為第一個參數:
1 const store = new Vuex.Store({ 2 state: { 3 todos: [ 4 { id: 1, text: '...', done: true }, 5 { id: 2, text: '...', done: false } 6 ] 7 }, 8 getters: { 9 doneTodos: state => { 10 return state.todos.filter(todo => todo.done) 11 } 12 } 13 })
在Vue中通過store.getters
對象調用。
1 computed: { 2 doneTodos () { 3 return this.$store.getters.doneTodos 4 } 5 }
Getter也可以接受其他getters作為第二個參數:
1 getters: { 2 doneTodos: state => { 3 return state.todos.filter(todo => todo.done) 4 }, 5 doneTodosCount: (state, getters) => { 6 return getters.doneTodos.length 7 } 8 }
mapGetters輔助函數
與mapState
類似,都能達到簡化代碼的效果。mapGetters
輔助函數僅僅是將store中的getters映射到局部計算屬性:
1 import { mapGetters } from 'vuex' 2 3 export default { 4 // ... 5 computed: { 6 // 使用對象展開運算符將 getters 混入 computed 對象中 7 ...mapGetters([ 8 'doneTodosCount', 9 'anotherGetter', 10 // ... 11 ]) 12 } 13 }
上面也可寫成:
1 computed: mapGetters([ 2 'doneTodosCount', 3 'anotherGetter', 4 // ... 5 ])
所以在Vue的computed
計算屬性中會存在兩種輔助函數:
1 import { mapState, mapGetters } form 'vuex'; 2 3 export default { 4 // ... 5 computed: { 6 mapState({ ... }), 7 mapGetter({ ... }) 8 } 9 }
Mutations
之前也說過了,更改Vuex的store中的狀態的唯一方法就是mutations
。
每一個mutation
都有一個事件類型type
和一個回調函數handler
。
1 const store = new Vuex.Store({ 2 state: { 3 count: 1 4 }, 5 mutations: { 6 increment (state) { 7 // 變更狀態 8 state.count++ 9 } 10 } 11 })
調用mutation
,需要通過store.commit
方法調用:
store.commit('increment')
Payload 提交載荷
也可以向store.commit
傳入第二參數,也就是mutation的payload
:
1 mutaion: { 2 increment (state, n) { 3 state.count += n; 4 } 5 } 6 7 store.commit('increment', 10);
單單傳入一個n
,可能並不能滿足我們的業務需要,這時候我們可以選擇傳入一個payload
對象:
1 mutation: { 2 increment (state, payload) { 3 state.totalPrice += payload.price + payload.count; 4 } 5 } 6 7 store.commit({ 8 type: 'increment', 9 price: 10, 10 count: 8 11 })
mapMutations函數
mutations也有映射函數mapMutations
,幫助我們簡化代碼,使用mapMutations
輔助函數將組件中的methods
映射為store.commit
調用。
1 import { mapMutations } from 'vuex' 2 3 export default { 4 // ... 5 methods: { 6 ...mapMutations([ 7 'increment' // 映射 this.increment() 為 this.$store.commit('increment') 8 ]), 9 ...mapMutations({ 10 add: 'increment' // 映射 this.add() 為 this.$store.commit('increment') 11 }) 12 } 13 }
Mutations必須是同步函數。
如果需要非同步操作,Mutations就不能滿足我們需求了,這時候我們就需要Actions
了。
作者:小郭
版權:本作品採用「署名-非商業性使用-相同方式共用 4.0 國際」許可協議進行許可。
本博文版權歸本博主所有,未經授權不得轉載