前言
學(xué)習(xí)vuex
之前,我提出了3個(gè)疑問。Vuex 官網(wǎng)
vuex
是什么侈玄?
官方文檔解釋:vuex
是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式
。
通俗點(diǎn)講就是把這個(gè)項(xiàng)目中需要多個(gè)地方或全局使用的狀態(tài)集中管理起來损话。vuex
應(yīng)用場(chǎng)景是什么?
舉個(gè)栗子
①多個(gè)組件依賴一種狀態(tài)槽唾。就是說這個(gè)狀態(tài)一改變丧枪,其他依賴這個(gè)狀態(tài)的組件都要跟著改變。如果是兄弟組件庞萍,使用傳值的方式的話就比較麻煩拧烦。
②多個(gè)組件共用同一個(gè)請(qǐng)求的數(shù)據(jù)。我比較懶钝计,又不想在多個(gè)組件寫相同的請(qǐng)求恋博,而且增加重復(fù)代碼,怎么辦私恬?這時(shí)候vuex
就派上用場(chǎng)了债沮。
從以上兩個(gè)栗子得出:需要集中管理共同狀態(tài)的都可以使用vuex
(不要濫用)vuex
怎么用?
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.store({
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... },
modules: { ... }
})
// index.js
import Vue from 'vue';
import store from '/store';
new Vue({
// 全局掛載 Vuex
store
})
在真正使用之前本鸣,你要了解 vuex
擴(kuò)展的幾個(gè)核心概念疫衩。
Vuex 核心概念
第一次看官方文檔的時(shí)候,對(duì)下面幾個(gè)概念不是很理解荣德,認(rèn)真看文檔闷煤,換個(gè)理解方式就好多了。
-
state
:管理狀態(tài)的地方涮瞻;可以類比成vue
里面的data
鲤拿。
注意:state(狀態(tài)) 不能像 data 的屬性那樣通過賦值改變,只能通過 mutations 改變署咽,這樣的目的是為了更好地追蹤狀態(tài)的變化
export default new Vuex.Store({
state: {
count: 1,
...
}
})
-
mutations
:改變state
(狀態(tài))的地方近顷;可以類比成vue
里面的methods
。
mutations
里面所有回調(diào)函數(shù)
接受的第一個(gè)參數(shù)是state
,其余參數(shù)是commit
傳的幕庐。
注意:mutations 是同步觸發(fā)的,無法監(jiān)聽回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變家淤;那我要寫異步請(qǐng)求改變狀態(tài)怎么辦异剥,actions 才是干這事的。
export default new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 改變狀態(tài)絮重;也就是修改 state 里面 count 的值
state.count++
}
}
})
那怎么調(diào)用mutations
的方法
改變state
冤寿?通過commit
(提交)的方式。
// ...
mutations: {
increment (state, n) {
state.count += n
},
increment1 (state, params) {
state.count += params.amount
}
}
// ***.vue
// 普通方式提交
this.$store.commit('increment', 10)
// 以對(duì)象形式提交
this.$store.commit({
type: 'increment1',
amount: 10
})
-
actions
:類似于mutation
青伤,但不同的是①actions
提交的是mutation
督怜,而不是直接改變state
; ②actions
可以包含任意異步操作狠角。
actions
接受的第一個(gè)參數(shù)是Store
實(shí)例具有相同方法和屬性的context
對(duì)象号杠,其余參數(shù)是dispatch
分發(fā)的
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
incrementAsync(context) {
context.commit('increment')
},
// 參數(shù)解構(gòu)
incrementAsync1 ({ commit, getters }, params) {
commit('increment')
},
// 回調(diào)方式提交
incrementAsync2 ({ commit, getters }, params) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
那怎么調(diào)用actions
的方法? 通過dispatch
(分發(fā))的方式丰歌。
// 以普通方式分發(fā)
this.$store.dispatch('incrementAsync')
// 以載荷形式分發(fā)
this.$store.dispatch('incrementAsync1', {
amount: 10
})
// 以對(duì)象形式分發(fā)
this.$store.dispatch({
type: 'incrementAsync2',
amount: 10
})
-
getters
:可以看做是Store
實(shí)例的計(jì)算屬性姨蟋;用法與vue
的計(jì)算屬性一致。
getters
的返回值會(huì)根據(jù)它的依賴被緩存起來立帖,且只有當(dāng)它的依賴值發(fā)生了改變才會(huì)被重新計(jì)算眼溶。
getters
只接受兩個(gè)參數(shù)state
、getters
晓勇。要是實(shí)現(xiàn)給getter
傳參堂飞,只能通過讓getter
返回一個(gè)函數(shù)。
export default 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)
},
// 接收兩個(gè)參數(shù)
doneTodos1: (state, getters) => {
return getters.doneTodos.length
},
// 返回一個(gè)函數(shù)
doneTodos2: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
})
調(diào)用 getters
注意:getter 在通過方法訪問時(shí)绑咱,每次都會(huì)去進(jìn)行調(diào)用绰筛,而不會(huì)緩存結(jié)果。
// 通過屬性調(diào)用
this.$store.getters.doneTodos1
// 通過方法調(diào)用
this.$store.getters.doneTodos2(1)
-
modules
:模塊的意思描融;每個(gè)模塊擁有自己的state
别智、mutation
、actions
稼稿、getters
薄榛、甚至是嵌套子模塊。
當(dāng)項(xiàng)目非常復(fù)雜時(shí)候让歼,將Store
分割成多個(gè)module
(模塊)管理的話維護(hù)起來就方便多了敞恋。
// ...
export default new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
總結(jié)
- 如果認(rèn)真看完就會(huì)發(fā)現(xiàn)與官網(wǎng)給的核心概念的目錄順序不同,我建議看文檔的順序是先看
state
谋右、mutation
硬猫、actions
,然后再看getters
、modules
啸蜜,這樣相對(duì)容易理解坑雅。 - 詳情請(qǐng)移步 Vuex 官網(wǎng)