在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
}
}