npm install --save vuexvue
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
count: 0,
...
}
const store = new Vuex.Store({
state,
mutations: {
handleFunctions() {
// xxx
}
}
});
export default store
複製代碼
main.jsvuex
import store from './store'
new Vue({
store,
render: h => h(App),
}).$mount('#app')
複製代碼
Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態npm
computed: {
count () {
return this.$store.state.count
}
}
複製代碼
每當 this.$store.state.count
變化的時候, 都會從新求取計算屬性,而且觸發更新相關聯的 DOM。數組
當一個組件須要多個狀態時,須要爲每個狀態都聲明爲計算屬性,固然,優秀的程序猿是不會這樣的作的,這樣就用到了mapState
緩存
適用場景:組件須要多個狀態bash
<template>
<p>{{ count }}</p>
<p>{{ countAlias }}</p>
<p>{{ countPlusLocalState }}</p>
</template>
// 在使用狀態的組件中
import { mapState } from 'vuex'
export default {
...
data() {
return {
localCount: 0
}
}
computed: mapState({
// 函數方式(傳統)
count: state => state.count,
// 傳入state子節點名稱的字符串
countAlias: 'count',
// 可以使用 `this` 獲取局部狀態(組件本身的狀態),必須使用常規函數
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
複製代碼
上邊的computed
等價於app
computed: {
count() {
return this.$store.state.count;
},
countAlias() {
return this.$store.state.count;
},
countPlusLocalState() {
return this.$store.state.count + this.localCount;
}
}
複製代碼
當映射的計算屬性的名稱與 state
的子節點名稱相同時,mapState
中傳一個字符串數組函數
// src/store/index.js
const state = {
count: 0,
countAlias: 1,
...
}
// 引用組件中
computed: mapState([
'count',
'countAlias'
])
等價於:
computed: {
count() {
return this.$store.state.count;
},
countAlias() {
return this.$store.state.countAlias;
}
}
複製代碼
當computed
計算屬性中既包含了state
狀態,又包含了組件私有的計算屬性時,可使用對象擴展運算符ui
computed: {
localCount() {
// 組件私有計算屬性
},
...mapState({
// state狀態收集
...
})
}
複製代碼
適用場景:須要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾並計數this
通常寫法:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
複製代碼
短板:若是有多個組件須要用到此屬性,要麼複製這個函數,或者抽取到一個共享函數而後在多處導入它——不管哪一種方式都不是很理想
改進:
// src/store/index.js
const store = new Vuex.Store({
state: {
todos: [
{id: 1, text: '...', done: 1},
{id: 2, text: '...', done: 2}
]
}
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done);
},
// 將其餘getter做爲第二個參數
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
},
// 返回一個函數
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
},
mutations: {
// ...
}
})
複製代碼
在 store 中定義「getter」(能夠認爲是 store 的計算屬性)。就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。也能夠經過讓 getter 返回一個函數,來實現給 getter 傳參。在對 store 裏的數組進行查詢時很是有用
Getter接收state爲其第一個函數,其餘getter做爲第二個函數。
getter 在經過方法訪問時,每次都會去進行調用,而不會緩存結果 在其餘組件中使用
this.$store.getters.doneTodos;
this.$store.getters.getTodoById(2);
複製代碼
mapGetters
輔助函數
mapGetters
輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性,使用同mapState
使用
import { mapGetters } from 'vuex';
複製代碼
在Vuex中更改狀態的惟一方式是提交commit,this.$store.commit('increment')
,每一個mutation都有一個事件類型(type) 和一個 回調函數(handler),狀態的更改在回調函數中進行
const store = new Vuex.Store({
state: {
// ...
},
mutations: {
increment (state){
// ... 這裏的‘increment’即type,函數體爲回調函數
}
}
})
複製代碼
能夠在this.$store.commit
時傳入額外的參數,如this.$store.commit('increment', 100)
,這個叫作mutation的載荷,大多狀況下載荷是一個對象
// store/index.js
mutations: {
increment (state, obj){
state.count += obj.num
}
}
// xxx.vue
this.$store.commit('increment', {
num: 100,
name: 'a'
})
=> 提交方式2:對象提交方式,mutation的回調函數保持不變
this.$store.commit({
type: 'increment',
num: 100,
name: 'a'
})
複製代碼
注意事項:
Mutation必須是同步函數
mapMutations
將組建的methods
映射爲store.commit
調用
export default {
// ...
methods: {
...mapMutations([
'increment', // 將 `this.increment()` 映射爲 `this.$store.commit('increment')`
// `mapMutations` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射爲 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 將 `this.add()` 映射爲 `this.$store.commit('increment')`
})
}
}
複製代碼