寫在文前:
最近一直在用vue開發(fā)項(xiàng)目,寫來寫去就是那么些方法只锻,對(duì)于簡(jiǎn)單的項(xiàng)目一些常用的vue方法足以解決,但是涉及到頁(yè)面狀態(tài)樱溉,權(quán)限判斷等一些復(fù)雜的傳值挣输,vuex是必須的。對(duì)于vuex也運(yùn)用一段時(shí)間福贞,但是總覺得少了點(diǎn)什么撩嚼,或者停留在會(huì)用的狀態(tài),理解不了精髓挖帘,當(dāng)然了估計(jì)水平還沒達(dá)到完丽。所以一直想找個(gè)時(shí)間總結(jié)一下vuex。一來深入的了解拇舀,二來也方便以后查閱逻族。
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: { count: 0 },
mutations: {
increment (state) {
state.count++
}
}
})
以上就是一個(gè)最簡(jiǎn)單的Vuex,每一個(gè)Vuex應(yīng)用就是一個(gè)store骄崩,在store中包含組件中的共享狀態(tài)state和改變狀態(tài)的方法(暫且稱作方法)mutations聘鳞。
vuex的核心是:state,getter,actions,mutations
1、state
state就是根據(jù)你項(xiàng)目的需求要拂,自己定義的一個(gè)數(shù)據(jù)結(jié)構(gòu)抠璃,里面可以放些通用的狀態(tài)。
const state = {
openId:"",
storeId:"",
storeName:''
}
例如上面所寫的脱惰,這些狀態(tài)可以在各個(gè)頁(yè)面通過vuex訪問搏嗡。如下:
this.$store.state.openId = "111"
之前我一直通過上面的方式來修改state里面的狀態(tài)值,行拉一,肯定能用彻况,但是好像官方并不建議我們這樣使用,而是建議使用mutations來改變state里面的值舅踪,因?yàn)椴煌ㄟ^mutations改變state,狀態(tài)不會(huì)被同步良蛮。至于mutations下面會(huì)講到抽碌。
2、getter
getter怎么理解呢决瞳?通俗的理解可以認(rèn)為是getter里的函數(shù)就是vuex里的計(jì)算屬性货徙,類似于computed函數(shù)。
const store = new Vuex.Store({
state: {
count: 0
},
getters: { // getters
countAdd: function (state) {
return state.count++
}
},
mutations: {
increment (state) {
state.count++
}
}
})
getter函數(shù)怎么用呢皮胡?如上vuex里定義了一個(gè)getter函數(shù)countAdd痴颊。我們可以在vue文件里的computed計(jì)算屬性里引用,如下屡贺。
computed: {
...mapGetters{["countAdd"]}
show:function(){
alert("這個(gè)是測(cè)試頁(yè)面")
}
}
這樣我們可以直接在vue頁(yè)面里取到countAdd的值{{countAdd}}即為1蠢棱⌒可保可惜在我的項(xiàng)目里目前還沒用到getter,可能寫的少了泻仙,還沒理解其中的要義糕再。
3、mutations
官方定義:更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation玉转。Vuex 中的 mutations 非常類似于事件:每個(gè) mutation 都有一個(gè)字符串的 事件類型 (type) 和 一個(gè) 回調(diào)函數(shù) (handler)突想。這個(gè)回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的地方,并且它會(huì)接受 state 作為第一個(gè)參數(shù):
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變更狀態(tài)
state.count++
}
}
})
你不能直接調(diào)用一個(gè) mutation handler究抓。這個(gè)選項(xiàng)更像是事件注冊(cè):“當(dāng)觸發(fā)一個(gè)類型為 increment 的 mutation 時(shí)猾担,調(diào)用此函數(shù)〈滔拢”要喚醒一個(gè) mutation handler绑嘹,你需要以相應(yīng)的 type 調(diào)用 store.commit 方法:
store.commit('increment')
也可以向store.commit傳入第二參數(shù),也就是mutation的payload:
mutaion: {
increment (state, n) {
state.count += n;
}
}
store.commit('increment', 10);
但是有時(shí)候怠李,單個(gè)傳入n可能并不能滿足我們的業(yè)務(wù)需要圾叼,這時(shí)候我們可以選擇傳入一個(gè)payload對(duì)象:
mutation: {
increment (state, payload) {
state.totalPrice += payload.price + payload.count;
}
}
store.commit({
type: 'increment',
price: 10,
count: 8
})
不例外,mutations也有映射函數(shù)mapMutations捺癞,幫助我們簡(jiǎn)化代碼夷蚊,使用mapMutations輔助函數(shù)將組件中的methods映射為store.commit調(diào)用。
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations({
add: 'increment' // 映射 this.add() 為 this.$store.commit('increment')
})
}
}
這樣我們可以在vue文件里直接調(diào)用函數(shù):this.add()而不用this.$store.commit('increment')這樣寫了髓介,簡(jiǎn)化了很多惕鼓。
需要注意:Mutations必須是同步函數(shù)。
如果我們需要異步操作唐础,Mutations就不能滿足我們需求了箱歧,這時(shí)候我們就需要Actions了。
4一膨、action
Action 類似于 mutation呀邢,不同在于:
Action 提交的是 mutation,而不是直接變更狀態(tài)豹绪。
Action 可以包含任意異步操作价淌。
官方demo如下:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
如果我在vue頁(yè)面里想用action,我們可以分發(fā) Action瞒津,Action 通過 store.dispatch 方法觸發(fā):
store.dispatch('increment')
Actions 支持同樣的載荷方式和對(duì)象方式進(jìn)行分發(fā):
// 以載荷形式分發(fā)
store.dispatch('incrementAsync', {
amount: 10
})
// 以對(duì)象形式分發(fā)
store.dispatch({
type: 'incrementAsync',
amount: 10
})
我們也可以運(yùn)用其映射函數(shù):mapActions
methods:{
...mapActions{[
"add":"increment "http://函數(shù)命名不相同
// "increment ":"increment "http://函數(shù)命名相同
]}
}
調(diào)用:this.add()即可蝉衣。相同時(shí)候調(diào)用:this.increment()
Modules
由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象巷蚪。當(dāng)應(yīng)用變得非常復(fù)雜時(shí)病毡,store 對(duì)象就有可能變得相當(dāng)臃腫。
為了解決以上問題屁柏,Vuex 允許我們將 store 分割成模塊(module)啦膜。每個(gè)模塊擁有自己的 state有送、mutation、action功戚、getter娶眷、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割:
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 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)
總結(jié)起來:mutation 只管存,你給我(dispatch)我就存啸臀;action只管中間處理届宠,處理完我就給你,你怎么存我不管(所有的改變state狀態(tài)的都是mutation 來操作)乘粒;Getter 我只管取豌注,我不改的(類似計(jì)算屬性)。
關(guān)于vuex目前也就了解這么多灯萍,在實(shí)際項(xiàng)目中vuex用什么轧铁,怎么用,還需要靈活改變旦棉,以后慢慢摸索吧齿风。上面的示例很多都是vuex文檔上的,總結(jié)起來還是需要多看文檔绑洛,在實(shí)際項(xiàng)目中運(yùn)用救斑,才是最好的辦法吧。