vuex為狀態管理器,主要用於全局狀態管理,方便組件間的狀態共享。其主要涉及Store、Mutation、Action、Getter
vuex思想:
通過定義和隔離狀態管理中的各種概念並通過強制規則維持視圖和狀態的獨立性,代碼更結構化且更易維護。
state:用來數據共享數據存儲
mutation:用來注冊改變數據狀態
getters:用來對共享數據進行過濾操作
action:解決異步改變共享數據
state 驅動應用的數據源 view 以聲明方式將state映射到視圖 actions 響應在view上的用戶輸入導致的狀態變化
每一個vuex應用的核心就是store倉庫,即一個容器,其包含着應用中的大部分的狀態state。
vuex的狀態存儲是響應式的:當vue組件從store中讀取狀態時,若store中的狀態發生變化,則相應的組件也會相應地得到高效更新。
不能直接改變store中的狀態:改變store中狀態的唯一途徑即是顯示地提交mutation。
state:
vuex使用單一狀態樹,即一個對象包含了全部的應用層級狀態,唯一數據源,每一個應用僅包含一個store實例。
vuex狀態存儲是響應式的,從store實例中讀取狀態最簡單方法是在計算屬性中返回某個狀態:
Getter:
getter的返回值會根據它的依賴被緩存起來,只有當它的依賴值發生了改變才會被重新計算。
const store = new Vuex.Store({
state:{
todos:[
{id:1, text:'dd', done:true},
{id:2, text:'d2d', done:false}
]
},
getters:{
doneTodos:state => {
return state.todos.filter(todo => todo.done)
}
}
})
通過屬性訪問:store.getters.doneTodos,getter 在通過屬性訪問時是作為 Vue 的響應式系統的一部分緩存其中的
通過方法訪問:getter 在通過方法訪問時,每次都會去進行調用,而不會緩存結果
getters:{
getTodoById:(state)=>(id)=>{
return state.todos.find(todo=>todo.id===id)
}
}
store.getters.getTodoById(2)
mapGetters輔助函數:僅是將 store 中的 getter 映射到局部計算屬性
import {mapGetters} from 'vuex';
export default {
computed:{
...mapGetters(['count','amount'])
}
}
ps:若將getter屬性領取一個名字,使用對象形式:
mapGetters({
count:newCount
})
mutation:
更改vuex的store中的狀態的唯一方法是提交mutation,每個mutation都有一個字符串的事件類型type和一個回調函數handler,
handler即是實際進行狀態更改的地方,且接受state作為第一個參數。
ps: 最好提前在store中初始化所有所需屬性;新添加屬性如想具有響應式,則推薦使用Vue.set(obj,'newProp,123)或 vm.$set(target,key,value)或者以新對象替換老對象,
如state.obj={...state.obj, newProp:123}
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 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters
來獲取 state 和 getters。
Action 通過 store.dispatch 方法觸發:store.dispatch('increment')
store.dispatch 可以處理被觸發的 action 的處理函數返回的 Promise,並且 store.dispatch 仍舊返回 Promise
一個 store.dispatch 在不同模塊中可以觸發多個 action 函數。在這種情況下,只有當所有觸發函數完成后,返回的 Promise 才會執行
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象,當應用非常復雜時,store會很臃腫。=》出現了將store分割成module,每個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 的狀態
computed:{
...mapGetters(['memberInfo'])
},
methods:{
...mapActions(['GetInfo', 'GetShopList']),
}
// state
// getters 批量導出state中的值
// action提交mutation
// store.dispatch觸發action操作
參考 & 感謝:vuex官網 & 各路大神
