本文基本上是官方教程的盜版,用通俗易懂的文字講解Vuex,也對原文內容有刪減。javascript
若是你對以上聲明不介意,那麼就能夠繼續看本文,但願對你有所幫助。html
學習一個新技術,必需要清楚兩個W,"What && Why"。vue
"XX 是什麼?","爲何要使用 XX ,或者說 XX 有什麼好處",最後纔是"XX 怎麼使用"。java
Vuex 相似 Redux 的狀態管理器,用來管理Vue的全部組件狀態。vuex
當你打算開發大型單頁應用(SPA),會出現多個視圖組件依賴同一個狀態,來自不一樣視圖的行爲須要變動同一個狀態。app
遇到以上狀況時候,你就應該考慮使用Vuex了,它能把組件的共享狀態抽取出來,當作一個全局單例模式進行管理。這樣無論你在何處改變狀態,都會通知使用該狀態的組件作出相應修改。less
下面講解如何使用Vuex。異步
本文就不涉及如何安裝Vuex,直接經過代碼講解。函數
import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } })
以上就是一個最簡單的Vuex,每個Vuex應用就是一個store,在store中包含組件中的共享狀態state
和改變狀態的方法(暫且稱做方法)mutations
。學習
須要注意的是隻能經過mutations
改變store的state
的狀態,不能經過store.state.count = 5;
直接更改,state
至關於對外的只讀屬性。
使用store.commit
方法觸發mutations
改變state
:
store.commit('increment');
console.log(store.state.count) // 1
一個簡簡單單的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
選項,提供了一種機制將狀態從根組件注入到每個子組件中。
// 根組件 import Vue from 'vue'; import Vuex form 'vuex'; Vue.use(Vuex); const app = new Vue({ el: '#app', store, components: { Counter }, template: ` <div class="app"> <counter></counter> </div> ` })
經過這種注入機制,就能在子組件Counter
經過this.$store
訪問:
// Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } }
computed: {
count () {
return this.$store.state.count } }
這樣經過count
計算屬性獲取同名state.count
屬性,是否是顯得過重複了,咱們可使用mapState
函數簡化這個過程。
import { mapState } from 'vuex'; export default { computed: mapState ({ count: state => state.count, countAlias: 'count', // 別名 `count` 等價於 state => state.count }) }
還有更簡單的使用方法:
computed: mapState([
// 映射 this.count 爲 store.state.count 'count' ])
若是咱們須要對state
對象進行作處理計算,以下:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length } }
若是多個組件都要進行這樣的處理,那麼就要在多個組件中複製該函數。這樣是很沒有效率的事情,當這個處理過程更改了,還有在多個組件中進行一樣的更改,這就更加不易於維護。
Vuex中getters
對象,能夠方便咱們在store
中作集中的處理。Getters接受state
做爲第一個參數:
const store = new Vuex.Store({
state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } })
在Vue中經過store.getters
對象調用。
computed: {
doneTodos () {
return this.$store.getters.doneTodos } }
Getter也能夠接受其餘getters做爲第二個參數:
getters: {
doneTodos: state => { return state.todos.filter(todo => todo.done) }, doneTodosCount: (state, getters) => { return getters.doneTodos.length } }
與mapState
相似,都能達到簡化代碼的效果。mapGetters
輔助函數僅僅是將store中的getters映射到局部計算屬性:
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用對象展開運算符將 getters 混入 computed 對象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
上面也能夠寫做:
computed: mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ])
因此在Vue的computed
計算屬性中會存在兩種輔助函數:
import { mapState, mapGetters } form 'vuex'; export default { // ... computed: { mapState({ ... }), mapGetter({ ... }) } }
以前也說過了,更改Vuex的store中的狀態的惟一方法就是mutations
。
每個mutation
都有一個事件類型type
和一個回調函數handler
。
const store = new Vuex.Store({
state: { count: 1 }, mutations: { increment (state) { // 變動狀態 state.count++ } } })
調用mutation
,須要經過store.commit
方法調用mutation type
:
store.commit('increment')
也能夠向store.commit
傳入第二參數,也就是mutation的payload
:
mutaion: {
increment (state, n) { state.count += n; } } store.commit('increment', 10);
單單傳入一個n
,可能並不能知足咱們的業務須要,這時候咱們能夠選擇傳入一個payload
對象:
mutation: {
increment (state, payload) { state.totalPrice += payload.price + payload.count; } } store.commit({ type: 'increment', price: 10, count: 8 })
不例外,mutations也有映射函數mapMutations
,幫助咱們簡化代碼,使用mapMutations
輔助函數將組件中的methods
映射爲store.commit
調用。
import { mapMutations } from 'vuex' export default { // ... methods: { ...mapMutations([ 'increment' // 映射 this.increment() 爲 this.$store.commit('increment') ]), ...mapMutations({ add: 'increment' // 映射 this.add() 爲 this.$store.commit('increment') }) } }
注 Mutations必須是同步函數。
若是咱們須要異步操做,Mutations就不能知足咱們需求了,這時候咱們就須要Actions
了。