寫在文前:
最近一直在用vue開發項目,寫來寫去就是那么些方法,對于簡單的項目一些常用的vue方法足以解決,但是涉及到頁面狀態,權限判斷等一些復雜的傳值,vuex是必須的。對于vuex也運用一段時間,但是總覺得少了點什么,或者停留在會用的狀態,理解不了精髓,當然了估計水平還沒達到。所以一直想找個時間總結一下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++
}
}
})
以上就是一個最簡單的Vuex,每一個Vuex應用就是一個store,在store中包含組件中的共享狀態state和改變狀態的方法(暫且稱作方法)mutations。
vuex的核心是:state,getter,actions,mutations
1、state
state就是根據你項目的需求,自己定義的一個數據結構,里面可以放些通用的狀態。
const state = {
openId:"",
storeId:"",
storeName:''
}
例如上面所寫的,這些狀態可以在各個頁面通過vuex訪問。如下:
this.$store.state.openId = "111"
之前我一直通過上面的方式來修改state里面的狀態值,行,肯定能用,但是好像官方并不建議我們這樣使用,而是建議使用mutations來改變state里面的值,因為不通過mutations改變state,狀態不會被同步。至于mutations下面會講到。
2、getter
getter怎么理解呢?通俗的理解可以認為是getter里的函數就是vuex里的計算屬性,類似于computed函數。
const store = new Vuex.Store({
state: {
count: 0
},
getters: { // getters
countAdd: function (state) {
return state.count++
}
},
mutations: {
increment (state) {
state.count++
}
}
})
getter函數怎么用呢?如上vuex里定義了一個getter函數countAdd。我們可以在vue文件里的computed計算屬性里引用,如下。
computed: {
...mapGetters{["countAdd"]}
show:function(){
alert("這個是測試頁面")
}
}
這樣我們可以直接在vue頁面里取到countAdd的值{{countAdd}}即為1。可惜在我的項目里目前還沒用到getter,可能寫的少了,還沒理解其中的要義。
3、mutations
官方定義:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutations 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變更狀態
state.count++
}
}
})
你不能直接調用一個 mutation handler。這個選項更像是事件注冊:“當觸發一個類型為 increment 的 mutation 時,調用此函數。”要喚醒一個 mutation handler,你需要以相應的 type 調用 store.commit 方法:
store.commit('increment')
也可以向store.commit傳入第二參數,也就是mutation的payload:
mutaion: {
increment (state, n) {
state.count += n;
}
}
store.commit('increment', 10);
但是有時候,單個傳入n可能并不能滿足我們的業務需要,這時候我們可以選擇傳入一個payload對象:
mutation: {
increment (state, payload) {
state.totalPrice += payload.price + payload.count;
}
}
store.commit({
type: 'increment',
price: 10,
count: 8
})
不例外,mutations也有映射函數mapMutations,幫助我們簡化代碼,使用mapMutations輔助函數將組件中的methods映射為store.commit調用。
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations({
add: 'increment' // 映射 this.add() 為 this.$store.commit('increment')
})
}
}
這樣我們可以在vue文件里直接調用函數:this.add()而不用this.$store.commit('increment')這樣寫了,簡化了很多。
需要注意:Mutations必須是同步函數。
如果我們需要異步操作,Mutations就不能滿足我們需求了,這時候我們就需要Actions了。
4、action
Action 類似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接變更狀態。
Action 可以包含任意異步操作。
官方demo如下:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
如果我在vue頁面里想用action,我們可以分發 Action,Action 通過 store.dispatch 方法觸發:
store.dispatch('increment')
Actions 支持同樣的載荷方式和對象方式進行分發:
// 以載荷形式分發
store.dispatch('incrementAsync', {
amount: 10
})
// 以對象形式分發
store.dispatch({
type: 'incrementAsync',
amount: 10
})
我們也可以運用其映射函數:mapActions
methods:{
...mapActions{[
"add":"increment "http://函數命名不相同
// "increment ":"increment "http://函數命名相同
]}
}
調用:this.add()即可。相同時候調用:this.increment()
Modules
由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。
為了解決以上問題,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 的狀態
總結起來:mutation 只管存,你給我(dispatch)我就存;action只管中間處理,處理完我就給你,你怎么存我不管(所有的改變state狀態的都是mutation 來操作);Getter 我只管取,我不改的(類似計算屬性)。
關于vuex目前也就了解這么多,在實際項目中vuex用什么,怎么用,還需要靈活改變,以后慢慢摸索吧。上面的示例很多都是vuex文檔上的,總結起來還是需要多看文檔,在實際項目中運用,才是最好的辦法吧。