• vuex——模块化


    一、什么是vuex module,为什么要使用vuex模块化?

    模块化,就是将vuex分为不同的模块,无论从项目上还是结构上,都容易维护,我们在平时写的vuex中,都是在一个文件中,写state、getters、mutations、actions。想象一下,如果我们的项目特别大,比如淘宝那么大,那么我们vuex中要维护的内容会特别多的时候,例如“购物车”需要用到vuex,“设置”需要用到vuex,“首页”也需要用到vuex,那么如果我们都写到一个文件中,就会出现代码相当的“臃肿”。这一个store文件最后好几万行代码。还怎么维护?

    所以,我们vue官网就给出了办法,使用vuex模块化开发。

    今天我们简单学习使用,学会后,你要查阅官网,深入学习,才能提高这个技术。

    模块化有很多写法,今天按照我的习惯,简单的写一下,我们和以前一样,需要下载vuex,会得到一个store文件夹,内部我们有一个index跟文件。并且,我们需要自己创建一个modules文件夹,里边放入我们想要区分的js模块文件,你想分成多少个模块,就分成多少个,我目前写了俩个模块,一个是购物车car.js,一个是我的my.js,type.js先不用管。如图:

    首先我们需要先将modules中的所有文件引入到index.js根文件中(以前我们是导出mutations等方法,现在这个文件中,我只引入了模块,所以只需要导出模块),如下(index.js):

    import Vue from "vue";
    import Vuex from "vuex";
    
    // 引入两个模块文件
    import car from './modules/car';
    import my from './modules/my';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      modules: {
        car,
        my
      }
    });

     然后我们就可以在每个模块当中,写入独立的state、mutations等等。这样我们在使用的时候,购物车就用car.js;我的就用my.js。用购物车car.js举例(其他文件同理),如下(car.js):

    const state = {
    
    }
    
    const getters = {
    
    }
    
    const mutations = {
    
    }
    
    const actions = {
        
    }
    
    export default {
        namespaced: true,
        state,
        getters,
        mutations,
        actions
    }
    

    这里就可以像以前一样写我们的vuex方法了。细心的同学会注意到,我们导出时,会多出一个namespaced:true,一般我们在模块使用时,都会加入这个属性。

    命名空间:namesapced:true,当模块被注册后,它的所有getter、action及mutation都会自动根据模块注册的路径调整命名,也就是说,我们在调用这些方法时,需要加上这个文件的路径(比如我要访问这个文件中的state里边的某个属性:this.$store.state.car。后边这个car就是多了个car.js模块名,因为如果不加模块名,那我们会访问所有模块中的属性,那就乱了),所以我们要加上命名空间,相当于独立的区块去使用,模块和模块之间互不干扰。

    和平时一样,我们跟个案例:

    点击增加数值(car.js):

    const state = {
        number: 100
    }
    
    const getters = {
    
    }
    
    const mutations = {
        add(){
            state.number ++;
        }
    }
    
    const actions = {
        
    }
    
    export default {
        namespaced: true,
        state,
        getters,
        mutations,
        actions
    }
    

    我们重点说一下vue中怎么获取模块中的内容。我们可以和平常一样,直接用this.$store.state.car.number来获取到state中的number内容。我们今天说说在项目中最常使用的:辅助函数mapState、mapGetters、mapActions和mapMutations。

    不一一举例,简单说两个mapState和mapActions,深入理解可去看官网

    我们在使用时,需要先引入:

    import { mapState, mapActions } from 'vuex';
    

    这两个函数,前者写在计算属性computed中,后者写在方法methods中。

    在写入时,需要用到展开符...,它可以将内容一一的展开。

    举个例子:

    let a = [1, 2, 3];
    let b = [4, 5, 6];
    let c = [...a, ...b];
    console.log(c);   // [1, 2, 3, 4, 5, 6]
    

    那我们获取一下state中的number:

    computed: {
      ...mapState({
        a: state => state.car.number
      })
    },
    methods: {
      ...mapMutations(['car/add']),
      add(){
        this['car/add']()   // 注意,这里this后没有点
      }
    },
    

    展开mapState,定义一个a,然后返回state中的car模块下的number常量。展开mapMutations,返回是个数组,数组中是个字符串,返回car模块下的add方法,定义一个add,直接触发就可以。有人会问,触发mutations中的方法不是应该用commit吗,答案是我们用了mapMutations,它会将这个路径直接映射成commit方法,所以我们直接用就行,这也是与原来的区别。

    我们定义的这个a,就是想要的数值,可以在标签中展示出来,add也直接使用。

    <h2>{{a}}</h2>
    <button @click="add">点击增加</button>
    

    这样写出来,是好用的,但是看起来会有问题。想一下,car是个模块,我们现在只是举例而已,但是如果我们在开发中,这个模块下命名空间比较深入,还有其他模块,一层一层比较多,就会变成这个样子:

    computed: {
        ...mapState({
    
          a: state => state.car.xx.xx.xx.number
          // 如果下边还有很多,就要写很多重复的 car.xx.xx.xx,如:
          b: state => state.car.xx.xx.xx.name
          c: state => state.car.xx.xx.xx.key
        })
      },
    
     methods: {
        ...mapMutations(['car/xx/xx/xx/add']),
        add () {
          this['car/xx/xx/xx/add']()
        }
      }
    

    这个层层的嵌套,那就要写很多重复的car/xx/xx/xx,所以我们可以,将这个模块当作字符串提取出来,换个写法,按照我们的举例:

    computed: {
      ...mapState('car', {
        a: state => state.number
      })
    },
    methods: {
      ...mapMutations('car', ['add']),
    },
    

    如上所示,我们可以将他作为参数,放到前面,这样所有绑定都会自动将该模块作为上下文,写出来也简单不少。当然我们还可以再简化一些。我们可以通过使用createNamesapcedHelpers创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数。

    就是我们可以从vuex中引入createNamespacedHelpers,然后将刚才的字符串作为参数,传进来,如下:

    // 这里引入createNamespacedHelpers
    import { createNamespacedHelpers } from 'vuex';
    // 定义mapState、mapMutations,并将car传入createNamespacedHelpers
    const { mapState, mapMutations } = createNamespacedHelpers('car');
    
    computed: {
      ...mapState({
        a: state => state.number
      })
    },
    methods: {
      ...mapMutations(['add']),
    },
    

    这就是vuex模块化,写法都很多,看我们自己的习惯,当然了,我们在模块中,还可以使用常量替代Mutation事件类型。在多人开发时,我们知道mutations中放入了方法,如果有很多方法,多人协作时找起来会比较麻烦,那我们可以创建一个放入常量的文件(前文中我们创建的type.js文件),在里边我们可以定义常量,但注意的是,我们开发中习惯常量要大写,单词之间用下划线分开。并且,在模块中引入这个文件:

    一、首先,我们创建一个js文件,我们前文图片中的type.js,在里边创建一个常量,开发时前后要一致,并加以标注:

    // 前后都要大写,一般前后名称一致,但是为了我们能够理解,本次我们写两个
    // 开发中,我们应该这样写:export const ADD_NUMBER = 'ADD_NUMBER'
    // 本次我们定义前后不一样的
    
    export const ADD_NUMBER = 'AAA'   // 点击增加数字
    

    二、在car模块中引入type.js并使用引入进来的常量:// 按需引入常量import { ADD_NUMBER } from './type';

    const state = {
        number: 100
    }
    
    const getters = {
    
    }
    
    const mutations = {
        // 使用常量命名,注意,这里[ADD_NUMBER]映射出来的名称,其实是AAA
        // 我们写成固定的数字,也可以设置参数、灵活传参
        // 第一个参数是state,第二个参数是传入参数payload
        [ADD_NUMBER](state, payload){
            state.number += payload;
        }
    }
    
    const actions = {
        
    }
    
    export default {
        namespaced: true,
        state,
        getters,
        mutations,
        actions
    }
    

      

    三、vue页面,由于刚才我们用了payload参数,所以我们也需要传入参数,然后我们可以思考下,我们触发的名称应该写哪一个?

    methods: {
      // 思考一下问号的地方,应该写 ADD_NUMBER还是AAA?
      ...mapMutations(['AAA']),
    },

    这个问题也就是我刚才故意在常量中,前后不一样的原因,由于我们前后都写一样,有些小白会不知道,这里定义的到底是前边的名称,还是后边字符串的名称。答案是AAA,也是ES6中对象的扩展写法。

    最后的写法是这样的:

    <h2>{{a}}</h2>
    <button @click="aaa(2)">点击增加</button>
    
    computed: {
      ...mapState({
        a: state => state.number
      })
    },
    methods: {
      // 思考一下问号的地方,应该写 ADD_NUMBER还是AAA?
      // ...mapMutations(['AAA']),
      
      // 我们除了可以写成数组,还可以用对象的写法
      ...mapMutations({
        aaa: 'AAA'
      })
    
      // 你可以按照原始写法写,当然要去掉标签中的参数,参数改成下边传递。
      // aaa(){
      //   this.$store.commit('car/AAA', 100);
      // }
    
    },
    

    这就是modules模块化的开发写法,希望看完,你们会有所收获。

     来源:https://yq.aliyun.com/articles/738863

  • 相关阅读:
    MFC Windows 程序设计>WinMain 简单Windows程序 命令行编译
    AT3949 [AGC022D] Shopping 题解
    CF643D Bearish Fanpages 题解
    CF643C Levels and Regions 题解
    CF241E Flights 题解
    CF671C Ultimate Weirdness of an Array 题解
    CF1592F Alice and Recoloring 题解
    GYM 102452E 题解
    CF494C Helping People 题解
    P5556 圣剑护符
  • 原文地址:https://www.cnblogs.com/xulinjun/p/13918160.html
Copyright © 2020-2023  润新知