• 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">1option>
          <option value="2">2option>
          <option value="3">3option>
        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">1option>
          <option value="2">2option>
          <option value="3">3option>
        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"}),
    
  • 相关阅读:
    MyBatis ---- 自定义映射resultMap
    Docker的常用基础命令(详细讲解)
    EasyV数字孪生流域|宁波智慧水利整体智治综合应用
    PyTorch深度学习(二)【反向传播、用pytorch实现线性回归】
    深度强化学习中Double DQN算法(Q-Learning+CNN)的讲解及在Asterix游戏上的实战(超详细 附源码)
    From Java To Kotlin:空安全、扩展、函数、Lambda很详细,这次终于懂了
    作为前端你还不懂MutationObserver?那Out了
    【LeetCode刷题】面试题 17.19. 消失的两个数字
    赋能智能安防,数字化采购协同管理平台助力企业采购精细化管理
    3D 线激光相机的激光条纹中心提取方法
  • 原文地址:https://blog.csdn.net/Vest_er/article/details/126943082