state:
state即Vuex中的基本數據!
state就是用來存放數據,若是對數據進行處理輸出,比如數據要過濾,一般我們可以寫到computed中。但是如果很多組件都使用這個過濾后的數據,這就是getters存在的意義。我們可以認為,【getters】是store的計算屬性。
getters(相當於State的計算屬性) :
1基礎用法:
main.js:
const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
}
}
})
index.vue:
<script>
export default {
name: "index.vue",
computed: {
list() {
return this.$store.getters.filteredList;
}
}
}
</script>
2.內部依賴
getter 可以依賴其它已經定義好的 getter。比如我們需要統計過濾后的列表數量,就可以依賴之前定義好的過濾函數。
main.js:
const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
},
listCount: (state, getters) => {
return getters.filteredList.length;
}
}
})
index.vue:
<template>
<div>
過濾后的列表:{{list}}
<br>
列表長度:{{listCount}}
</div>
</template>
<script>
export default {
name: "index.vue",
computed: {
list() {
return this.$store.getters.filteredList;
},
listCount() {
return this.$store.getters.listCount;
}
}
}
</script>
mutation(提交更改數據的方法,同步!必須是同步函數) :
使用vuex修改state時,有兩種方式:
1)可以直接使用 this.$store.state.變量 = xxx;
2)this.$store.dispatch(actionType, payload)或者 this.$store.commit(commitType, payload)
main.js:
const store = new Vuex.Store({
strict: true, // strict: true, 若開啟嚴格模式只要不經過 mutation的函數,則會報錯
state: {
cartNum: 0, // 購物車數量
},
mutations: {
// 加1
INCREMENT(state) {
state.cartNum++;
},
}
})
index.vue:
import baseStore from '../../../main.js';
methods: {
addCarts () {
baseStore.commit('INCREMENT')
},
}
異同點:
1)共同點: 能夠修改state里的變量,並且是響應式的(能觸發視圖更新)
2)不同點:
若將vue創建 store 的時候傳入 strict: true, 開啟嚴格模式,那么任何修改state的操作,只要不經過
mutation的函數,
vue就會 throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
action(像一個裝飾器,包裹mutations,使之可以異步。) :
action的功能和mutation是類似的,都是去變更store里的state,不過action和mutation有兩點不同:
1)action主要處理的是異步的操作,mutation必須同步執行,而action就不受這樣的限制,也就是說action中我們既可以處理同步,也可以處理異步的操作
2)action改變狀態,最后是通過提交mutation
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
setInterval(function(){
context.commit('increment')
}, 1000)
}
}
})
注意:Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters。
分發actions
Action 通過 store.dispatch 方法觸發:
store.dispatch('increment')
modules ( 模塊化Vuex):
背景:在Vue中State使用是單一狀態樹結構,應該的所有的狀態都放在state里面,如果項目比較復雜,那state是一個很大的對象,store對象也將對變得非常大,難於管理。
module:可以讓每一個模塊擁有自己的state、mutation、action、getters,使得結構非常清晰,方便管理
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 的狀態