在學習Vuex以前,先了解一下「單向數據流」css
這個狀態自管理應用包含如下幾個部分:vue
state,驅動應用的數據源; view,以聲明方式將 state 映射到視圖; actions,響應在 view 上的用戶輸入致使的狀態變化。(好比請求數據或者修改數據會致使數據源狀態改變)
可是遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞,並且特別不方便。
若是堅持使用,傳參的方法對於多層嵌套的組件將會很是繁瑣,各類各樣的問題一般會致使沒法維護的代碼。es6
因此咱們把組件的共享狀態抽取出來,以一個全局單例模式管理(惰性單例的設計模式)
每個 Vuex 應用的核心就是 store(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。Vuex 和單純的全局對象有如下兩點不一樣:ajax
Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。vuex
你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化,從而讓咱們可以實現一些工具幫助咱們更好地瞭解咱們的應用。vue-cli
對,Vuex核心就是它的store,其中,有三個重要的部分,
State:
經過它存取多個組件共享的數據
Mutations:
經過這個對象中的方法,能夠改變State中的數據,但在這以前,必須經過顯式地提交(commit) 來觸發其中的方法。
Actions:
提交mutation,能夠包含任意異步操做
這一步不是必要的,前提是你不須要異步操做,例如ajax請求數據,設計模式
如下內容基於vue-cli寫的,請先完成這一步異步
一般Vuex會單獨寫在一個js文件中,工具
// 引入vue 和 vuex 模塊 import Vue from 'vue' import Vuex from 'vuex' // 中間件,使用VueX做爲Vue的一個參數 Vue.use(Vuex)
數據,相似組件中的data學習
const state = { // count: 0 }
計算屬性,相似組件中的computed
const getters = { // evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' }
用戶派發的行爲,相似methods
const actions = { // increment: ({commit}) => commit('increment') }
必須經過這一步來修改數據
const mutations = { // increment: ({count}) => { // state.count++ // } }
導出這個對象
export default new Vuex.Store({ state, getters, actions, mutations })
而後在main.js的Vue實例中,註冊一個store(倉庫)
import store from './store' new Vue({ ... store, ... })
接下來從組件(視圖)開始,理解一下這個過程
Vue-component:
用戶的特定行爲(須要使用Vuex的狀況) 會派發一個任務給Actions 或者直接給Mutations
寫在App.vue組件中
HTMT
<div @click="add"> {{ count }} </div>
JS
methods: { add () { // 派發一個任務,叫作'increment' this.$store.dispatch('increment') } }
Actions
:
Actions是用戶指定的行爲,這裏沒有異步操做,因此直接commit到Mutations
const actions = { // const { commit } = store // commit === store.commit increment: ({commit}) => commit('increment') // es6的寫法,它等同於這樣: // increment ({commit}) { // commit('increment') // } }
Mutations:
Mutations如上所述,修改一下state的數據
const mutations = { increment: ({count}) => { state.count++ } }
state:
state的數據被改變
Vue-component:
最後回到了組件這裏,經過計算屬性獲取到改變的數據並顯示到頁面上
count () { return this.$store.state.count }
另外,咱們但願實現這麼一個小的效果:count爲偶數時爲綠色,奇數時爲紅色,那麼咱們在store中經過getters實現(固然在組件中經過計算屬性也能夠實現,這裏只是爲了說明getters的做用)
const getters = { // evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' }
在App.vue中的computed中寫上
evenOrOdd (state) { return this.$store.getters.evenOrOdd }
在模板中補充一點:
:class="evenOrOdd"
和對應的css:
.even { color: green; } .odd { color: red; }