当前位置:首页 » 《随便一记》 » 正文

Vuex④(多组件共享数据、Vuex模块化+namespace)

20 人参与  2023年05月07日 13:29  分类 : 《随便一记》  评论

点击全文阅读


文章目录

多组件共享数据代码实现 Vuex模块化总结

多组件共享数据

我们现在想实现这种情况:
在这里插入图片描述

Person组件的总人数就是Person中列表的长度

br上的是Count组件,br下的是Person组件。

我们通过vuex中的state实现一些数据的多组件共享:在这里插入图片描述

代码实现

Person.vue

<template><div><h1>人员列表</h1><h3 style="color:red">Count组件求和为:{{sum}}</h3><input type="text" placeholder="请输入名字" v-model="name"><button @click="add">添加</button><ul><li v-for="p in personList" :key="p.id">{{p.name}}</li></ul></div></template><script>import {nanoid} from 'nanoid'export default {name:'Person',data() {return {name:''}},computed:{personList(){return this.$store.state.personList},sum(){return this.$store.state.sum}},methods: {add(){const personObj = {id:nanoid(),name:this.name}this.$store.commit('ADD_PERSON',personObj)this.name = ''}},}</script>

注意点:

这里使用了id生成类nanoid,如果要使用先安装包

yarn add nanoid或者npm install nanoid

使用方法:

import { nanoid } from 'nanoid'const person = {name:'张三', age:18}// 最后用nanoid给它添加一个idperson.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"

Count.vue

<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{bigSum}}</h3><h3>我在{{school}},学习{{subject}}</h3><h3 style="color:red">Person组件的总人数是:{{personList.length}}</h3><select v-model.number="n"><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="incrementOdd(n)">当前求和为奇数再加</button><button @click="incrementWait(n)">等一等再加</button></div></template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用户选择的数字}},computed:{//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState(['sum','school','subject','personList']),//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters(['bigSum'])},methods: {//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations({increment:'JIA',decrement:'JIAN'}),//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},mounted() {// const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})// console.log(x)},}</script><style lang="css">button{margin-left: 5px;}</style>

store

//该文件用于创建Vuex中最为核心的storeimport Vue from 'vue'//引入Vueximport Vuex from 'vuex'//应用Vuex插件Vue.use(Vuex)//准备actions——用于响应组件中的动作const actions = {/* jia(context,value){console.log('actions中的jia被调用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被调用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被调用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被调用了')setTimeout(()=>{context.commit('JIA',value)},500)}}//准备mutations——用于操作数据(state)const mutations = {JIA(state,value){console.log('mutations中的JIA被调用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被调用了')state.sum -= value},ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}}//准备state——用于存储数据const state = {sum:0, //当前的和school:'尚硅谷',subject:'前端',personList:[{id:'001',name:'张三'}]}//准备getters——用于将state中的数据进行加工const getters = {bigSum(state){return state.sum*10}}//创建并暴露storeexport default new Vuex.Store({actions,mutations,state,getters})

Vuex模块化

我们查看我们前面的代码不难发现一个问题:那就是多个组件的代码都放在了唯一的actions、mutations、state、getters中,我们前面的案例中只涉及到了两个组件,但是如果我们有几百个几千个组件,这些代码全部堆积到一起,会非常的繁杂。所以我们想对他进行一个分类,将各组件的代码分离开来。

原来我们是这样:
在这里插入图片描述

现在我们变成这样:
在这里插入图片描述
每个配置里面都有其各自的actions、mutations、state、getters。

也就是说现在的store结构发生了变化:
在这里插入图片描述

当然这个a,b起的有点随便,我们稍微语义化一下:
在这里插入图片描述

因为接口暴露的形式发生了变化,接下来我们的组件里面就要发生一些变化。

先来看看Count.vue:

原来是这样:
在这里插入图片描述
现在变成了这样:
在这里插入图片描述

还有一种方法:
在这里插入图片描述

最后我们还有最重要的一步:给配置的命名空间打开。
在这里插入图片描述
如果我们缺失了这一步,这些map的第一个参数,countAbout、personAbout这些是识别不出来的!

computed:{//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState('countAbout',['sum','school','subject']),...mapState('personAbout',['personList']),//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters('countAbout',['bigSum'])},methods: {//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},

接下来我们修改Person.vue,这里我们不使用map方法,而是使用原生的方法看看怎么修改:
在这里插入图片描述
我们上面的firstPersonName这样写是因为:
我们原来store里的state是长这样的:
在这里插入图片描述
但是现在我们store里的getters是长这样的:
在这里插入图片描述
也就是他的key变成了这种形式,但是我们在使用的对象的属性的时候如果使用的是.这种语法那么这个/是不能使用的,凭借js语法的特性我们可以使用[]语法去访问它的属性。

在这里插入图片描述

最后我们还可以对最后一次优化,那就是把分类后的代码分文件放置:
在这里插入图片描述

我们来看看这几个文件:

count.js

//求和相关的配置export default {namespaced:true,actions:{jiaOdd(context,value){console.log('actions中的jiaOdd被调用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被调用了')setTimeout(()=>{context.commit('JIA',value)},500)}},mutations:{JIA(state,value){console.log('mutations中的JIA被调用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被调用了')state.sum -= value},},state:{sum:0, //当前的和school:'尚硅谷',subject:'前端',},getters:{bigSum(state){return state.sum*10}},}

person.js

//人员管理相关的配置import axios from 'axios'import { nanoid } from 'nanoid'export default {namespaced:true,actions:{addPersonWang(context,value){if(value.name.indexOf('王') === 0){context.commit('ADD_PERSON',value)}else{alert('添加的人必须姓王!')}},addPersonServer(context){axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(response => {context.commit('ADD_PERSON',{id:nanoid(),name:response.data})},error => {alert(error.message)})}},mutations:{ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被调用了')state.personList.unshift(value)}},state:{personList:[{id:'001',name:'张三'}]},getters:{firstPersonName(state){return state.personList[0].name}},}

index.js

//该文件用于创建Vuex中最为核心的storeimport Vue from 'vue'//引入Vueximport Vuex from 'vuex'import countOptions from './count'import personOptions from './person'//应用Vuex插件Vue.use(Vuex)//创建并暴露storeexport default new Vuex.Store({modules:{countAbout:countOptions,personAbout:personOptions}})

总结

模块化+命名空间

目的:让代码更好维护,让多种数据分类更加明确。

修改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'}),

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/61355.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1