当我们想要在vue框架下实现数据传输自由时,我们学习了父子传递和非父子组件通信,但是数据从哪来,这要求数据的存储需要有一个规范的仓库,这个仓库就是vuex,如何创建一个仓库:
1.我们在src下创建一个store文件夹用于存储各种数据,并创建一个index.js用于创建全局仓库数据。
2.编写index.js
import Vue from 'vue' import Vuex from 'vuex' import cart from './modules/cart' Vue.use(Vuex) export default new Vuex.Store({ state: { }, getters: { }, mutations: { }, actions: { }, modules: { cart } })
index.js包含五个部分:
1.state数据:这部分用来写用于存储的基本数据
2.getters:类似于computed属性,用来返回计算好的数据
3.mutations:这部分类似于方法,用于直接操作state里的数据
4.actions:这部分用于异步操作数据,如axios访问或者计时器处理为异步操作,一般在actions里会调用mutations里的方法,用来异步操作数据(mutations不能进行异步操作)
5.modules:模块数据,用来将其他模块化仓库整合到index.js中
需要注意的是,以上五类都是写在index.js中或者模块仓库js中的以及被封装好的,在文件内直接调用处理数据。其本身是需要被组件进行调用的,
1其中state类似于data(),要return 仓库数据。
2mutations里的方法第一个参数为state,(可以换别的名字,但是怎么换都是指代state),我们用这个state.数据名 可以用来获取仓库的数据并操作。第二个参数是用户可以操作的传入参数。注意,最多除了state,只能写一个参数,如果想要传递多个操作数据可以传一个对象或者数组。
3actions:用于进行异步操作,相当于对mutations做一个包装,完成其不能完成的异步操作,注意,actions里的第一个参数为context上下文,当使用actions调用mutations的方法时要用context.commit(‘mutations方法名’,操作参数(可选))
4.getters:相当于computed属性,计算state的各个值等待被调用
5.modules:当开发大型项目时,我们不方便把一大堆数据全都堆到index.js,十分不方便维护,我们可以像导入组件那样,把vuex模块化,我们在store下创建modules,在modules下写各个子组件的js代码,其写法就和index.js差不多了
import axios from 'axios' export default { namespaced: true, state () { return { cartlist: [] } }, mutations: { updatelist (state, newlist) { state.cartlist = newlist }, UpdateCount (state, obj) { const thisobj = state.cartlist.find(item => item.id === obj.id) thisobj.count = obj.newCount } }, actions: { async getlist (context) { const newlist = await axios.get('http://localhost:3000/cart') // console.log(newlist.data) context.commit('updatelist', newlist.data) }, async updateListAs (context, obj) { console.log(obj) await axios.patch(`http://localhost:3000/cart/${obj.id}`, { count: obj.newCount }) context.commit('UpdateCount', obj) } }, getters: { totalCount (state) { return state.cartlist.reduce((sum, item) => sum + item.count, 0) }, totalPrice (state) { return state.cartlist.reduce((sum, item) => sum + item.price * item.count, 0) } } }
上面写的五种方法都是写在仓库js中的,我们需要在组件内调用。如何调用分为两大类方法:
直接原生调用和map辅助函数调用
1.state调用
1)state的直接调用
在组件使用state时,模块中直接调用{{$store.state.数据名}}
script内调用多加一个this:this.$store.state.数据名
2)state的mapstate调用
import { mapState } from 'vuex'
然后再computed内写
computed:{ ...mapState(['totalCount', 'totalPrice']) }
这样组件就可以直接调用totalCount和totalPrice了
2.getters的调用
1)getters的直接调用
与state很相似。在组件使用state时,模块中直接调用{{$store.getters.数据名}}
script内调用多加一个this:this.$store.getters.数据名
2)getters的mapgetters调用
import { mapGetters} from 'vuex'
computed:{ ...mapGetters(['totalCount', 'totalPrice']) }
这样就可以直接调用{{totalCount}}获取计算属性了
3.mutations的调用
1)mutations的直接调用
我们再组件内调用mutations时,使用commit函数
如:this.$store.commit('方法名',传入参数)
2)mutations的mapMutations调用
与其他映射辅助函数类似,第一步先引入,但是第二步展开要写在method里,不同于state和getters写在 computed里
methods:{ ...mapMutations(['GetList']) }
4.actions的调用
1)还是,先是直接调用,使用dispatch,除此之外,与mutations一样
语法:this.$store.dispatch('方法名',参数)
2.actions的mapActions调用
methods:{ ...mapActions(['GetList']) }
小结
综上所述,使用map映射辅助函数可以极大的提升效率,但切记要引入什么辅助函数就写什么。
import { mapGetters, mapActions, mapMutations, mapState } from 'vuex'