Vuex是經過建立一個store的實例並配置相應的配置項來管理公共狀態的javascript
1、State:vuex中的‘data’vue
組 件中引入vuex中的store實例後經過store.state.屬性來訪問vuex中統一管理的數據,組件中從vuex中讀取狀態最簡單的方法是在計算屬性中,這樣vuex中的狀態變化的時候計算屬性就會從新求取計算屬性,並更新domjava
使用store中的state問題一:每一個組件使用的時候都須要引入store,vuex
解決:經過根實例中註冊store選項,該store實例就會注入到根組件下的全部子組件,子組件中經過this.$store訪問數組
問題二:當一個組件須要多個狀態時須要定義多個計算屬性,很繁瑣,promise
解決:可使用輔助函數mapState來統一導入dom
// 在單獨構建的版本中輔助函數爲 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 } }) } 當映射的計算屬性的名稱與 state 的子節點名稱相同時,咱們也能夠給 mapState 傳一個字符串數組。 computed: mapState([ // 映射 this.count 爲 store.state.count 'count' ])
問題三:上述能總體引入屬性了,可是沒有辦法將它與局部計算屬性混合使用異步
解決:使用對象展開運算符,將上邊的mapState前邊加上…,在寫其餘的計算屬性就能夠混合使用了函數
computed: { localComputed () { /* ... */ }, // 使用對象展開運算符將此對象混入到外部對象中 ...mapState({ // ... }) }
注意:雖然vuex方便管理狀態,可是沒有必要將全部的都放入vuex中,那樣會形成代碼冗長不直觀,能夠把須要公用的狀態放入vuex中this
2、Getter:vuex中的‘computed’
經過store中的state派生一些狀態的時候可使用getter,至關於組件中的computed,getter中接受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) } } }) //Getter 也能夠接受其餘 getter 做爲第二個參數 getters: { // ... doneTodosCount: (state, getters) => { return getters.doneTodos.length } } store.getters.doneTodosCount // -> 1
訪問方式:
屬性訪問:將store放入全局組件中後能夠經過this.$store.getters.doneTodosCount來訪問store中的計算屬性
方法訪問:經過讓 getter 返回一個函數,來實現給 getter 傳參
getters: { // ... getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
改善:getter中也會出現相似state中的問題,vuex一樣提供了輔助函數mapGetter
3、Mutation:vuex中的‘method’
不直接在state中改變狀態是由於統一使用mutation來改變能夠更好的追蹤到狀態的變化
組建中經過store.commit(vue中的方法名)來調用vuex統一管理的方法
Mutation中的方法中第一個是state,第二個能夠加入形參,在訪問的時候commit中第二個放入實參
Mutation必須是同步的函數
你能夠在組件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 輔助函數將組件中的 methods 映射爲 store.commit 調用(須要在根節點注入 store)
4、Action:因爲mutation只能是同步的函數因此須要action來執行異步的函數
Action 提交的是 mutation,而不是直接變動狀態
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } })
你能夠調用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters 來獲取 state 和 getters
你在組件中使用 this.$store.dispatch('xxx') 分發 action,或者使用 mapActions 輔助函數將組件的 methods 映射爲 store.dispatch 調用(須要先在根節點注入 store)
Action能夠經過promise來組合多個action來處理更加複雜的異步流程
表單中的雙向綁定
假設表單中綁定的是在計算屬性返回的屬於vuex store的對象,用戶輸入的時候就會試圖去直接改變vuex中的狀態,而通常不能直接修改vuex中的狀態
方法一:須要經過mutation去修改:給 <input>
中綁定 value,而後偵聽 input
或者 change
事件
<input :value="message" @input="updateMessage"> // ... computed: { ...mapState({ message: state => state.obj.message }) }, methods: { updateMessage (e) { this.$store.commit('updateMessage', e.target.value) } } //下面是 mutation 函數: // ... mutations: { updateMessage (state, message) { state.obj.message = message } }
方法二:在計算屬性的set中調用mutation來改變當前值,並在mutation中取得新的值進行賦值
<input v-model="message"> // ... computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }