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 > 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 國際」許可協議進行許可,
本博文著作權歸本博主所有,未經授權不得轉載
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/543580.html
標籤:其他
