目录
一、模块化与命名空间
1、目的
让store组件代码更有条理性,代码更好维护,数据分类更加明确
2、比较
3、模块化代码
const CountAbout = {
state:{...},
actions:{...},
mutations:{...},
getters:{...}
}
const CatsAbout = {
state:{...},
actions:{...},
mutations:{...},
getters:{...}
}
export default new Vuex.Store({
modules:{
CountAbout,
CatsAbout,
}
})
4、命名空间
开启命名空间:namespaced : true
二、多组件共享数据案例
store/index.js代码
//引入vue
import Vue from "vue";
//引入vuex库
import Vuex from "vuex";
// 使用vuex
Vue.use(Vuex)
//actions用于响应组件中用户的动作
const actions ={
odd({commit},num){
if(state.sum % 2 != 0){
commit("ODD",num)
}
},
};
//mutations用于修改数据(state)
const mutations ={
ADD(state,num){
state.sum += num;
},
ODD(state,num){
state.sum += num
},
ADDCAT(state,name){
state.cats.push(name)
}
};
//state保存具体的数据
const state = {
sum:0,
cats:['憨瓜','波妞','快来']
};
const getters = {
bigSum(state){
return state.sum*10
}
}
//暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
Count组件代码
<template>
<div>
<h3>Count组件当前求和为:{{sum}}</h3>
<select @click="selectNum($event)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add(num)">+</button>
<button @click="odd(num)">当和为奇数再加</button>
<h3>sum放大十倍是:{{bigSum}},<span>Cats组件猫咪个数为:{{cats.length}}</span></h3>
<input type="text" placeholder="请输入宠物名称" v-model="catName">
<button @click="addCat">添加宠物名称</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1,
catName:''
}
},
methods:{
...mapMutations({"add":"ADD"}),
...mapActions(["odd"]),
selectNum(){
this.num=Number(event.target.value)
},
addCat(){
this.$store.commit("ADDCAT",this.catName.trim());
this.catName=''
}
},
computed:{
...mapState(["sum","cats"]),
...mapGetters(["bigSum"])
}
}
</script>
<style scoped>
button {
margin-left: 5px;
}
span {
color: red;
}
</style>
Cats组件代码
<template>
<div>
<h3>Cats组件喵喵学员名称</h3>
<ul>
<li v-for="(cat,index) in cats" :key="index">
<span>{{cat}}</span>
</li>
</ul>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name:"Cats",
computed:{
...mapState(["cats"])
}
}
</script>
<style >
span {
margin-left: 10px;
}
</style>
运行结果
三、模块化代码
优化以上案例,让代码更具有条理性,更易于维护
index.js文件
//引入vue
import Vue from "vue";
//引入vuex库
import Vuex from "vuex";
// 使用vuex
Vue.use(Vuex);
//Count组件状态
const CountAbout = {
//开启命名空间
namespaced:true,
state:{
sum:0,
},
actions:{
odd(context,num){
if(context.state.sum % 2 != 0){
context.commit("ODD",num)
}
},
},
mutations:{
ADD(state,num){
state.sum += num;
},
ODD(state,num){
state.sum += num
},
},
getters:{
bigSum(state){
return state.sum*10
}
}
}
//Cats组件状态
const CatsAbout = {
namespaced:true,
state:{
cats:['憨瓜','波妞','快来']
},
mutations:{
ADDCAT(state,name){
state.cats.push(name)
}
}
}
export default new Vuex.Store({
modules:{
CountAbout,
CatsAbout,
}
})
Count组件代码
<template>
<div>
<h3>Count组件当前求和为:{{sum}}</h3>
<select @click="selectNum($event)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add(num)">+</button>
<button @click="odd(num)">当和为奇数再加</button>
<h3>sum放大十倍是:{{bigSum}},<span>Cats组件猫咪个数为:{{cats.length}}</span></h3>
<input type="text" placeholder="请输入宠物名称" v-model="catName">
<button @click="addCat">添加宠物名称</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1,
catName:''
}
},
methods:{
...mapMutations('CountAbout',{"add":"ADD"}),
...mapActions('CountAbout',['odd']),
selectNum(){
this.num=Number(event.target.value)
},
addCat(){
this.$store.commit("CatsAbout/ADDCAT",this.catName.trim());
this.catName=''
}
},
computed:{
...mapState('CountAbout',['sum']),
...mapState('CatsAbout',['cats']),
...mapGetters('CountAbout',['bigSum'])
}
}
</script>
<style scoped>
button {
margin-left: 5px;
}
span {
color: red;
}
</style>
Cats组件代码
<template>
<div>
<h3>Cats组件喵喵学员名称</h3>
<ul>
<li v-for="(cat,index) in $store.state.CatsAbout.cats" :key="index">
<span>{{cat}}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name:"Cats",
}
</script>
<style >
span {
margin-left: 10px;
}
</style>
四、案例注意项
1、context与commit
在action函数中,第一个参数可以用context
,也可以用{commit}
,当我们模块化时必须用context,使用{commit}会报错
报错截图
2、开启命名空间
模块化之后,必须开启命名空间来读取store中的状态
,不然会报错
报错代码
[vuex] module namespace not found in mapState(): CatsAbout/
五、总结
开启命名空间之后,组件中读取store中的状态
1、读取state
//方法一:直接读取
this.$store.state.CatsAbout.cats
//方法二:通过mapState读取
...mapState('CatsAbout',['cats']),
2、读取getters
//方法一:直接读取
this.$store.getters('CountAbout/bigSum')
//方法二:通过mapGetters读取
...mapGetters('CountAbout',['bigSum']),
3、调用dispatch
//方法一:直接读取
this.$store.dispatch('CountAbout/odd',num)
//方法二:通过mapActions读取
...mapActions('CountAbout',['odd']),
4、调用commit
//方法一:直接读取
this.$store.commit('CountAbout/ADD',num)
//方法二:通过mapMutations读取
...mapMutations('CountAbout',{"add":"ADD"}),