【vue】vuex实现组件间数据共享 vuex模块化编码 网络请求
目录
一、vuex实现组件间数据共享
二、 vuex模块化编码
三、网络请求
模块化+命名空间小结:
总结不易~ 本章节对我有很大的收获, 希望对你也是!!!
本节素材已上传Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/28._src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_%E5%A4%9A%E7%BB%84%E4%BB%B6%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE
有过前面vuex四个map的引入,极大的缩短了我们构建dispatch 和 commit过程的流程,现在我们来创建两个组件Count 和 Person来通过vuex进行组件间数据共享
多组件共享数据就变得很简单了,新建一个组件Person就跟Count访问sum一样的考以访问sum
一、vuex实现组件间数据共享
往vuex添加Person的添加用户方法:ADD_PERSON
// 准备mutations——用于操作数据(state)
const mutations = {JIA(state, value) {console.log('mutations被调用了')state.sum += value},JIAN(state, value) {state.sum -= value},// person 添加一个人没有什么业务逻辑, 可以直接在mytations里面直接进行添加ADD_PERSON(state, value) {console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}
}
// 准备state——用于存储数据
const state = {sum: 0,school: '武汉传媒学院',subject: '前端',personList: [{ id: '001', name: '张三' }]
}
Person来实现数据共享,拿取vuex里面的sum, 就直接...mapState就可以直接拿到
import {nanoid} from 'nanoid'
import {mapState, mapGetter, mapMuatations, mapActions} from 'vuex'
export default {name:'MyPerson',data() {return {name: ''}},computed: {...mapState(['personList', 'sum'])},methods: {add() {const personObj = {id:nanoid(), name:this.name}this.$store.commit('ADD_PERSON', personObj)this.name = ''}}
}
本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/29_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_vuex%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A0%81
二、 vuex模块化编码
现在就遇到一个问题我们现在是开发一个订单系统,那我们就会遇到一个订单的增删改查,一个商品的增删改查,总之很多很多不同的程序都往一个mutations里面挤,最后mutations就会变得十分的臃肿,最最容易造成的就是git的版本冲突!
那么将各个功能分离出来,也是我们必须具备的能力,也十分简单!
在vuex里面将各个功能的actions、mutations、state、getters都准备好,然后分别对每个组件的共都封装好一个对象来存储这个四个属性
// 求和功能相关的配置 写成一个对象就好
const countOptions = {// 准备actions——用于响应组件中的动作actions: {jiaOdd(context, value) {console.log('jiaOdd被调用了')console.log(context)if (context.state.sum % 2) context.commit('JIA', value)},jiaWait(context, value) {console.log('jiaWait被调用了')setTimeout(() => { context.commit('JIA', value) }, 500)}},// 准备mutations——用于操作数据(state)mutations: {JIA(state, value) {console.log('mutations被调用了')state.sum += value},JIAN(state, value) {state.sum -= value},},// 准备state——用于存储数据state: {sum: 0,school: '武汉传媒学院',subject: '前端',},// 准备getters——用于将state里面的数据进行加工getters: {bigSum(state) {return state.sum * 10}}
}// 人员管理功能相关的配置 写成一个对象就好
const personsOptions = {actions: {},mutations: {// person 添加一个人没有什么业务逻辑, 可以直接在mytations里面直接进行添加ADD_PERSON(state, value) {console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}},state: {personList: [{ id: '001', name: '张三' }]},getters: {}
}
将各个功能分割好后,就放在Vuex.store里面进行暴露,注意!!!modules是对你的功能配置进行重命名一样,如果懒,也可以采用对象的简写形式!
// 创建 并 暴露store
export default new Vuex.Store({modules: {countAbout: countOptions,personsAbout: personsOptions}
})
对外暴露后, 这里拿MyCount组件进行举例,你一看就懂怎么样引用vuex里面分割好的actions、mutations、state、getters属性
要想模板里面的属性名不变,就要提前在map里面解析好,这种引用方法还是挺简单的,一看就懂;同样MyPerson组件也是如此!!!
<template><div><h1>当前求和为:{{ sum }}</h1><h3>放大10倍的和:{{ bigSum }}</h3><h3>我在{{ school }},学习{{ subject }}</h3><select v-model="n" name="" id=""><!-- 加上v-bind 就是动态数据绑定 value里面的值会被当作js表达式进行解析 不再是字符串 --><option :value="1">1</option><option :value="2">2</option><option :value="3">3</option></select><button @click="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="jiaOdd(n)">当前求和为奇数再加</button><button @click="jiaWait(n)">等一等再加</button><h3 style="color: red;">Person组件的总人数是:{{ personList.length }}</h3></div>
</template><script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {name: 'MyCount',data() {return {n:1, // 用户当前选择的数字}},computed: {...mapState('countAbout', ['sum', 'school', 'subject']),...mapState('personsAbout', ['personList']),//数组写法...mapGetters('countAbout', ['bigSum'])},methods: {...mapMutations('countAbout', {increment:'JIA', decrement:'JIAN'}),...mapActions('countAbout', ['jiaOdd', 'jiaWait'])},mounted() {const x = mapState({he:'sum', xuexiao:'school', xueke:'subject'})console.log(x)}
}
</script>
那么此时分别将两个组件的功能都进行完整的分割后,最后的功能分割就来了!!!
const.js求和功能:
// 求和功能相关的配置 写成一个对象就好
export default {namespaced: true,// 准备actions——用于响应组件中的动作actions: {jiaOdd(context, value) {console.log('jiaOdd被调用了')console.log(context)if (context.state.sum % 2) context.commit('JIA', value)},jiaWait(context, value) {console.log('jiaWait被调用了')setTimeout(() => { context.commit('JIA', value) }, 500)}},// 准备mutations——用于操作数据(state)mutations: {JIA(state, value) {console.log('mutations被调用了')state.sum += value},JIAN(state, value) {state.sum -= value},},// 准备state——用于存储数据state: {sum: 0,school: '武汉传媒学院',subject: '前端',},// 准备getters——用于将state里面的数据进行加工getters: {bigSum(state) {return state.sum * 10}}
}
那么MyPersons组件问题就来了!计算属性里面我是map写的,可以很轻松的就解析vuex里面的内容,但是add方法里面呢?我却很麻烦才能拿到vuex里面功能分割后的内容!
person.js添加人员功能:
computed: {personList() {return this.$store.state.personsAbout.personList},sum() {return this.$store.state.countAbout.sum},firstPersonName() {return this.$store.getters['personsAbout/firstPersonName']}},methods: {add() {const personObj = {id:nanoid(), name:this.name}this.$store.commit('personsAbout/ADD_PERSON', personObj)this.name = ''},addWang() {const personObj = {id:nanoid(), name:this.name}this.$store.dispatch('personsAbout/addPersonWang', personObj)this.name = ''}}
所以还是比较推荐map写法的!毕竟那是配套的~
本节素材已上传至Gitee:yihaohhh/我爱Vue - Gitee.comhttps://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/29_src_%E6%B1%82%E5%92%8C%E6%A1%88%E4%BE%8B_vuex%E6%A8%A1%E5%9D%97%E5%8C%96%E7%BC%96%E7%A0%81
三、网络请求
最后就是网络请求这一条路我们还没有讲过,现在来说说~
在vuex的Person.js里面添加一个actions addPersonServer方法来随机添加一个人的名字
这个网址是每日一句,可以不断的刷新那种经典句子,有兴趣可以自己看看:https://international.v1.hitokoto.cn/ 然后进行axios请求,如果请求成功就得到d的对象itokoto然后进行添加即可
actions: {addPersonServer(context) {axios.get('https://international.v1.hitokoto.cn/').then(response => {console.log(response.data.hitokoto)context.commit('ADD_PERSON', { id: nanoid(), name: response.data.hitokoto })},error => {alert(error.message)})}},
最后就在MyPersons组件里面进行调用即可:
<button @click="addPersonServer">添加一个人,名字随机</button>addPersonServer() {this.$store.dispatch('personsAbout/addPersonServer')}
模块化+命名空间小结:
-
目的:让代码更好维护,让多种数据分类更加明确。
-
修改
store.js
const countAbout = {namespaced:true,//开启命名空间state:{x:1},mutations: { ... },actions: { ... },getters: {bigSum(state){return state.sum * 10}}}const personAbout = {namespaced:true,//开启命名空间state:{ ... },mutations: { ... },actions: { ... }}const store = new Vuex.Store({modules: {countAbout,personAbout}})
-
开启命名空间后,组件中读取state数据:
//方式一:自己直接读取this.$store.state.personAbout.list//方式二:借助mapState读取:...mapState('countAbout',['sum','school','subject']),
-
开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取this.$store.getters['personAbout/firstPersonName']//方式二:借助mapGetters读取:...mapGetters('countAbout',['bigSum'])
-
开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatchthis.$store.dispatch('personAbout/addPersonWang',person)//方式二:借助mapActions:...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
-
开启命名空间后,组件中调用commit
//方式一:自己直接committhis.$store.commit('personAbout/ADD_PERSON',person)//方式二:借助mapMutations:...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),