Vuex④(多组件共享数据、Vuex模块化+namespace)
文章目录
- 多组件共享数据
-
- 代码实现
- Vuex模块化
-
- 总结
多组件共享数据
我们现在想实现这种情况:

Person组件的总人数就是Person中列表的长度
br上的是Count组件,br下的是Person组件。
我们通过vuex中的state实现一些数据的多组件共享:
代码实现
Person.vue
人员列表
Count组件求和为:{{sum}}
- {{p.name}}
注意点:
这里使用了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
当前求和为:{{sum}}
当前求和放大10倍为:{{bigSum}}
我在{{school}},学习{{subject}}
Person组件的总人数是:{{personList.length}}
1 2 3 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) }, } button{ margin-left: 5px; }
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
}
})
总结
模块化+命名空间
-
目的:让代码更好维护,让多种数据分类更加明确。
-
修改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
//方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang',person) //方式二:借助mapActions: ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) -
开启命名空间后,组件中调用commit
//方式一:自己直接commit this.$store.commit('personAbout/ADD_PERSON',person) //方式二:借助mapMutations: ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/fcb195e924.html

