Vue学习第26天——vuex中的模块化和命名空间的详解及案例练习

一、模块化与命名空间

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"}),
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值