0


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

文章目录

多组件共享数据

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

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

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

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

代码实现

Person.vue

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

注意点:

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

yarnadd nanoid
或者
npminstall nanoid

使用方法:

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

Count.vue

<template><div><h1>当前求和为:{{sum}}</h1><h3>当前求和放大10倍为:{{bigSum}}</h3><h3>我在{{school}},学习{{subject}}</h3><h3style="color:red">Person组件的总人数是:{{personList.length}}</h3><selectv-model.number="n"><optionvalue="1">1</option><optionvalue="2">2</option><optionvalue="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'exportdefault{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><stylelang="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}}//创建并暴露storeexportdefaultnewVuex.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

//求和相关的配置exportdefault{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'exportdefault{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)//创建并暴露storeexportdefaultnewVuex.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 =newVuex.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//方式一:自己直接dispatchthis.$store.dispatch('personAbout/addPersonWang',person)//方式二:借助mapActions:...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  6. 开启命名空间后,组件中调用commit//方式一:自己直接committhis.$store.commit('personAbout/ADD_PERSON',person)//方式二:借助mapMutations:...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),

本文转载自: https://blog.csdn.net/zyb18507175502/article/details/127309724
版权归原作者 十八岁讨厌编程 所有, 如有侵权,请联系我们删除。

“Vuex④(多组件共享数据、Vuex模块化+namespace)”的评论:

还没有评论