Vuex④(多组件共享数据、Vuex模块化+namespace)
创始人
2024-01-20 22:40:21

文章目录

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

多组件共享数据

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

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

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

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

代码实现

Person.vue


注意点:

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

yarn add nanoid
或者
npm install nanoid

使用方法:

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

Count.vue


store

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import 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}
}//创建并暴露store
export 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中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//应用Vuex插件
Vue.use(Vuex)//创建并暴露store
export default new Vuex.Store({modules:{countAbout:countOptions,personAbout:personOptions}
})

总结

模块化+命名空间

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

  2. 修改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}
    })
    
  3. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
进口奶粉的排名 荷兰奶粉十大排... 越来越乱的国内奶粉市场让很多宝妈宝爸都不知道该如何选择奶粉品牌,宝宝的安全是第一位,奶粉的质量以及口...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
不用扬鞭自奋蹄 乘势而上千帆竞... 思明区正全力向“两个进位”目标发起冲刺,努力为建设高素质高颜值现代化国际化的厦门作出“思明贡献”。(...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...