Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。
所謂的狀態管理,作用就是定義狀態,修改狀態。
定義state
在vue里使用Vuex以及在vuex中定義狀態的方式:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
msg:'狀態管理里的msg'
},
mutations: {
},
actions: {
},
modules: {
}
})
與vueRouter類似首先將vuex通過vue.use方法注入到vue實例里,然后new一個store出來,每一個vuex的核心就是store(倉庫),根據vue單一狀態數規則,一個項目里僅需一個store,所有狀態都放到這里進行管理。
Getters
getters相當于store的計算屬性,接收store的state屬性座位第一個參數,也可以接收其他getter作為第二個參數
//getters使用方法
getters: {
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
//外部組件中使用它
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
修改狀態:
直接通過$store.status.count=XXX
這種方式是可以修改狀態的,但是這樣在嚴格模式下會報錯,并且不符合vuex修改狀態的流程。
更改store中的狀態的唯一方法應該是提交mutation。
嚴格模式:
僅需在創建store的時候傳入strict:true
const store = new Vuex.Store({
strict: true
});
通過mutations修改狀態:
//store中寫法
state: {
msg:'狀態管理里的msg',
count:0
},
mutations: {
//此種方法雖然也可以成功修改狀態,但是不是提倡的寫法,mutations里定義的方法默認第一個參數是state中的全部狀態
// addCountStatus(){
// this.state.count++;
// }
//提倡寫法
addCountStatus(state){
state.count++;
}
},
//外部使用時觸發方法:
methods:{
CountStatus(){
this.$store.commit('addCountStatus');
}
}
//定義一個方法,通過觸發該方法達到觸發store中的mutations方法的目的
提交mutation:
想要觸發mutations里面定義的方法,唯一的方式是$store.commit,commit方法傳參必須至少有一個能區分的唯一標識,這個標識就是type。
當 commit 的參數是一個對象的時候,對象里必須要有 type 字段,除了 type 字段,你還可以添加額外任意字段為載荷(payload)。
對象方式提交commit (參數是對象)
//外部觸發
changeStatus(count){
this.$store.commit({
type:'testChange',
payload:count
})
//store:
testChange(state,num){
console.log(num)//這里拿到的是全部的payload參數
state.count+=num.payload;
}
type做第一參數
以commit(type,[payload])的形式提交,官方稱此為以載荷形式提交。
store.commit("increment");
store.commit("increment", 10);
store.commit("increment", { count: 2 });//store中接收到的就是第二個參數中的傳值
在大多數情況下,payload 應該是一個對象,這樣可以包含多個字段并且記錄的 mutation 會更易讀。
在哪里使用mutation:
- Vue 應用的組件里,在組件里調用store.commit。
- 還有 store 的 action 里。
Action:
Action與mutation的不同點:
- Action 提交的是 mutation,而不是直接變更狀態。
- Action 可以包含任意異步操作。
注冊action:
注冊 action 就跟定義 mutation 一樣,除了 handler 的入參不同。(action下定義的方法是與store實例的對象一致的context對象,可以理解為拿到了全部),因此可以:
- context.commit 提交一個 mutation,
- context.state獲取 state。
- context.getters 獲取 getters。
分發Action(調用Action中定義的函數)
Action 通過 store.dispatch方法觸發:
// 以載荷形式分發
this.$store.dispatch("incrementAsync", {
XXX:xxx
});
// 以對象形式分發
this.$store.dispatch({
type: "incrementAsync",
XXX:xxx
});
Action處理異步
store.dispatch 可以處理被觸發的 action 的處理函數返回的 Promise,并且 store.dispatch 仍舊返回 Promise,因此,通過 async / await,很方便控制流程
不要想復雜了,js里怎么處理異步,在Action里面就怎么處理,Vuex只是把異步操作放到了Action里面,其他用法差不多。
actions: {
A(){
return new Promise((resove)=>{
setTimeout(() => {
console.log('A函數執行')
resove();
}, 3000);
})
},
async B(context){
await context.dispatch('A')
context.commit('logmutations')
}
},
Model
Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態