安裝配置
npm install vuex --save
我使用的vue-cli腳手架(不再強調),在main.js中引入並且配置到全局
import Vuex from 'vuex';
import storeConfig from './config/store.js';
Vue.use(Vuex);
const store = new Vuex.Store(storeConfig);
new Vue({
store,
render: h => h(App)
}).$mount('#app');
核心概念
那麼我就看一下store.js
有哪些內容吧:
const storeConfig = {
state: {
data: [],
},
};
export default storeConfig;
1. state
就是全局數據,在所有組件中都可以獲取到。這個沒什麼多說的。
在組件中如果要獲取store中的state,可以通過兩種方法:首先第一就是直接訪問
this.$store.state.data
可以看出,如果某個子組件中要多次使用store中的數據,那麼這樣寫起來會很囉嗦的,我們可以使用mapState
輔助函數來減少敲鍵盤的次數。
該函數返回一個對象,如果映射的計算屬性名稱和state中的名稱相同,可以直接傳入一個數組。
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['data',])
}
}
如果要對屬性進行重命名,可以傳入一個對象。使用的時候直接使用心得名稱即可。
...mapState({
myData: 'data'
})
2. getters
有時我們需要獲取state中的數據進行處理之後的數據,比如篩選之類的。並且這個處理之後的數據要在多個組件中使用,每個組件都寫處理方法肯定不是我們想要的,這時getter就很有用了。
const storeConfig = {
state: {
data: [],
},
getters: {
getList: (state, getters) => {
return state.data.filter(item=> item.id !== 0)
}
}
};
這樣就可以直接從getters中獲取處理過的數據,而且這個值是會被緩存的,如果計算的依賴不變化是不會重新計算的,減少了不必要的消耗。第二個參數表示getter也接受其他getter。
在組件中要獲取getter也是非常簡單的,有以下三種方法:
第一種,直接通過Getter暴露的對象訪問,
this.$store.getters.getList
第二種,如果getter的返回值是一個函數,我們可以通過調用方法的形式訪問,
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
this.$store.getters.getTodoById(5)
第三種,通過輔助函數mapGetters
訪問,使用方法和mapState
基本一致,可以接受一個數組,也可以接受一個對象來重命名。
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['getList',])
}
}
3. mutations
state中的數據是不能隨便修改的,只能通過提交mutation修改,
const storeConfig = {
state: {
count: 1
},
mutations: {
increment (state, n) {
state.count = state.count + n;
}
}
};
提交時可以通過commit
方法來提交,接受第二個參數作爲要傳給mutation的參數。這個參數可以是一個單一的值,大多數情況下我們需要的是一個對象。
this.$store.commit("increment", 10);
也可以通過mapMutations
輔助函數提交,合併到methods中,直接當方法調用即可。
import { mapMutations } from "vuex";
export default{
methods: {
...mapMutations(['increment '])
},
mounted(){
this.increment({num: 10});
}
}
補充:
- 使用常量代替mutation事件類型。這樣我們可以把所有的mutation提取到一個文件中單獨管理
mutationTypes.js
export const CHANGEDATA= 'CHANGEDATA'
import { CHANGEDATA} from 'mutationTypes.js'
//...
mutations:{
[CHANGEDATA](state){
...
}
}
// ...
- mutation必須是同步的,如果要想異步調用請看下面的actions
4. actions
actions其實就是給提交mutation添加了一箇中間環節,通過先分發Action,然後再action中提交mutation。重要的是action中沒有同步的限制。
這裏直接複製官網的一段代碼,懶得敲了,
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
action函數接受一個context參數,這個參數和store實例一樣,因此可以調用context.commit
,也可以通過它調用state或者getters等等。
我們可以使用ES6的參數結構來簡化代碼。
actions: {
increment ({ commit }) {
commit('increment')
}
}
接下來怎麼分發action呢?同樣的,可以直接調用dispatch方法分發,
this.$store.dispatch("increment");
也可以使用輔助函數mapActions
來分發。使用方法和之前的輔助函數都一樣,不廢話了。
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['increment']),
...mapActions({
add: 'increment' // 將 `this.add()` 映射爲 `this.$store.dispatch('increment')`
})
}
}