在vuex中還有其他三個概念,分別是action、getter、moduler,其實這三個概念多多少少大大小小都大同小異,接下來分別解釋。
1. action
前面提到在mutation是用作同步傳遞資料的,那麼非同步用誰呢?答案是action。為了方便devtools打個快照存下來,方便管理維護。所以說這個只是規範,而不是邏輯的不允許,只是為了讓這個工具能夠追蹤資料變化而已。
定義action
mutations: {
changeCount (state, newCount) {
state.count = newCount
}
}
actions: {
setAsyncCount (context, num) {
// 一秒後, 給一個數, 去修改 num
setTimeout(() => {
context.commit('changeCount', num)
}, 1000)
}
},
呼叫action兩種方法
- 元件中透過dispatch呼叫
setAsyncCount () {
this.$store.dispatch('setAsyncCount', 666)
}
- 輔助函式 -mapActions對映呼叫
import { mapActions } from 'vuex'
methods: {
...mapActions(['changeCountAction'])
bntClick(){
this.setAsyncCount()
}
}
//mapActions對映的程式碼 本質上是以下程式碼的寫法
//methods: {
// changeCountAction (n) {
// this.$store.dispatch('changeCountAction', n)
// },
//}
2. getter
類似於vue中的computed,進行快取,對於Store中的資料進行加工處理形成新的資料
具體操作類似於前幾種,這裡不做具體說明
3. modules
modules就是模組,這裡指的是vuex的模組,當專案太大時inde.js的各個核心就會太過臃腫,這時我們可以採用moudules分成一個一個小的模組
預設情況下,模組內部的 action 和 mutation 仍然是註冊在全域性名稱空間的——這樣使得多個模組能夠對同一個 action 或 mutation 作出響應。
如果希望你的模組具有更高的封裝度和複用性,你可以透過新增 namespaced: true 的方式使其成為帶名稱空間的模組。當模組被註冊後,它的所有 getter、action 及 mutation 都會自動根據模組註冊的路徑調整命名。
import axios from 'axios'
export default {
namespaced: true,
state () {
return {
list: []
}
},
mutations: {
updataList (state, payload) {
state.list = payload
},
updatanewCount (state, obj) {
const goods = state.list.find(item => item.id === obj.id)
goods.count = obj.newCount
}
},
actions: {
async getdata (ctx) {
const res = await axios.get('http://localhost:3000/cart')
ctx.commit('updataList', res.data)
},
async updataCountAction (ctx, obj) {
await axios.patch(`http://localhost:3000/cart/${obj.id}`, {
count: obj.newCount
})
ctx.commit('updatanewCount', {
id: obj.id,
newCount: obj.newCount
})
}
},
getters: {
totalCount (state) {
return state.list.reduce((sum, item) => sum + item.count, 0)
},
totalPrice (state) {
return state.list.reduce((sum, item) => sum + item.count * item.price, 0)
}
}
}
import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
export default {
name: 'App',
created () {
this.$store.dispatch('cart/getdata')
},
computed: {
...mapState('cart', ['list'])
...mapGetters('cart', ['totalCount', 'totalPrice'])
},
components: {
CartHeader,
CartFooter,
CartItem
}
}