Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。說白了,vuex就是用來管理數據的。javascript
直接下載或者CDN引入html
Vuex的核心就是store(倉庫),其包含應用中的大部分狀態。Vuex 和單純的全局對象有如下兩點不一樣:java
如今咱們來建立一個store:vuex
new Vuex.Store({ state:{ //...... }, mutations:{ } })
在這個store裏,包含了一個 state 對象和 mutations 緩存
state用來存儲初始化的數據,讀取數據使用 store.state.數據 。app
修改數據使用 mutations ,調用 mutations 裏的數據須要使用 commit()less
如今來嘗試使用如下vuex,作一個簡單的計數程序:異步
HTML函數
<div id="app"> </div> <template id="tpl"> <div> <tip></tip> <btn></btn> </div> </template>
javascript
var store = new Vuex.Store({ state:{ count:0 }, mutations:{ plus(state){ state.count++ }, less(state){ state.count-- } } }); var app=new Vue({ el:'#app', template:'#tpl', components:{ tip:{ template:'<div>{{$store.state.count}}</div>' }, btn:{ template:` <div> <input type="button" value="+" v-on:click="$store.commit('plus')"/> <input type="button" value="-" v-on:click="$store.commit('less')"/> </div> ` } }, store }}
因爲 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態:
// 建立一個 Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count } } }
每當 store.state.count 變化的時候, 都會從新求取計算屬性,而且觸發更新相關聯的 DOM。
當一個組件須要獲取多個狀態時候,將這些狀態都聲明爲計算屬性會有些重複和冗餘。爲了解決這個問題,咱們可使用 mapState 輔助函數幫助咱們生成計算屬性,讓你少按幾回鍵:
// 在單獨構建的版本中輔助函數爲 Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: mapState({ // 箭頭函數可以使代碼更簡練 count: state => state.count, // 傳字符串參數 'count' 等同於 `state => state.count` countAlias: 'count', // 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數 countPlusLocalState (state) { return state.count + this.localCount } }) }
有時候咱們須要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾並計數:
computed: { doneTodosCount () { return this.$store.state.todos.filter(todo => todo.done).length } }
若是有多個組件須要用到此屬性,咱們要麼複製這個函數,或者抽取到一個共享函數而後在多處導入它 —— 不管哪一種方式都不是很理想。
Vuex 容許咱們在 store 中定義『getters』(能夠認爲是 store 的計算屬性)。就像計算屬性同樣,getters的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。
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) } } }) store.getters.doneTodes
Getters 也能夠接受其餘 getters 做爲第二個參數:
getters: { // ... doneTodosCount: (state, getters) => { return getters.doneTodos.length } } store.getters.doneTodosCount
咱們能夠很容易地在任何組件中使用它:
computed: { doneTodosCount () { return this.$store.getters.doneTodosCount } }
mapGetters 輔助函數僅僅是將 store 中的 getters 映射到局部計算屬性:
computed:{ ...mapGetters([ // 使用對象展開運算符將 getters 混入 computed 對象中 'doneTodosCount', 'anotherGetters' ]) }
更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。Vuex 中的 mutations 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數:
const store = new Vuex.Store({ state:{ count:0 }, mutations:{ plus(state){ state.count++ }, less(state){ state.count-- } } });
你能夠向 store.commit 傳入額外的參數,即 mutation 的 載荷(payload):
const store = new Vuex.Store({ state:{ count:0 }, mutations:{ plus(state,n){ state.count+=n }, less(state,n){ state.count-=n } } }); this.$store.commit('plus',5) this.$store.commit('less',5)
Action 相似於 mutation,不一樣在於:
actions:{ plus(commit){ commit({type:'plus',n:5}) } }