Vuex Note


Vuex

1.概念

​ 在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

2.何时使用?

​ 多个组件需要共享数据时

3.工作原理图

Vuex 原理图(来源于官网)

4.搭建 vuex 环境

  1. 创建文件:src/store/index.js

    //引入Vue核心库
    import Vue from "vue";
    //引入Vuex
    import Vuex from "vuex";
    //应用Vuex插件
    Vue.use(Vuex);
    
    //准备actions对象——响应组件中用户的动作
    const actions = {};
    //准备mutations对象——修改state中的数据
    const mutations = {};
    //准备state对象——保存具体的数据
    const state = {};
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state,
    });
    
  2. main.js中创建 vm 时传入store配置项

    //引入store
    import store from "./store";
    
    //创建vm
    new Vue({
      el: "#app",
      render: (h) => h(App),
      store,
    });
    

5.基本使用

  1. 初始化数据、配置actions、配置mutations,操作文件store.js

    //引入Vue核心库
    import Vue from "vue";
    //引入Vuex
    import Vuex from "vuex";
    //引用Vuex
    Vue.use(Vuex);
    
    const actions = {
      //响应组件中的dispatch,传入的第一个参数context有commit,state,dispatch等属性
      jia(context, value) {
        context.commit("JIA", value);
      },
    };
    
    const mutations = {
      //执行mutate,改变state中的状态
      JIA(state, value) {
        state.sum += value;
      },
    };
    
    //初始化数据
    const state = {
      sum: 0,
    };
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state,
    });
    
  2. 组件中读取 vuex 中的数据:this.$store.state.sum

  3. 组件中修改 vuex 中的数据:this.$store.dispatch('action中的方法名',数据)this.$store.commit('mutations中的方法名',数据)

    备注:若没有网络请求或其他业务逻辑,组件中也可以直接 commit,即不写dispatch,直接写commit

6.getters 的使用

  1. 概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。

  2. store.js中追加getters配置

    const getters = {
     // bigSum 可以理解为一个计算属性
        bigSum(state){
            return state.sum * 10
        }
    }
    
    //创建并暴露store
    export default new Vuex.Store({
        ......
        getters
    })
    
  3. 组件中读取 getters 中的数据:this.$store.getters.bigSum

7.四个 map 方法的使用

  1. 为什么要使用 mapXXX 方法?
    当我们在组件中操作 store 中存储的数据时不可避免的要编写大量的 computed 和 methods,这样的操作十分繁琐,而使用 mapXXX 方法能简化我们的操作。例如借助 mapState() 方法可以帮我们生成相应的 computed,借助 mapActions() 方法可以帮我们生成相应的 methods,其他的方法同理。再使用 … 扩展运算符将生成的 computed 或 methods 展开。

  2. 首先需要在组件中导入 mapXXX 方法
    import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'

  3. mapState 方法:用于帮助我们映射state中的数据为计算属性

    computed: {
        //(对象写法)借助mapState生成计算属性:sum、school、subject
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
    
        //(数组写法)借助mapState生成与state中的数据同名的计算属性:sum、school、subject
        ...mapState(['sum','school','subject']),
    },
    
  4. mapGetters 方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //(对象写法)借助mapGetters生成计算属性:bigSum
        ...mapGetters({bigSum:'bigSum'}),
    
        //(数组写法)借助mapGetters生成同名的计算属性:bigSum
        ...mapGetters(['bigSum'])
    },
    
  5. mapActions 方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

    methods:{
        //(对象写法)靠mapActions生成:incrementOdd、incrementWait
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
        //(数组写法)靠mapActions生成同名的:jiaOdd, jiaWait
        ...mapActions(['jiaOdd','jiaWait'])
    }
    
  6. mapMutations 方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //(对象写法)靠mapActions生成:increment、decrement
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
        //(数组写法)靠mapMutations生成同名的methods:JIA、JIAN
        ...mapMutations(['JIA','JIAN']),
    }
    

注意:借助 mapActions 与 mapMutations 生成的 methods 需要向 actions 和 mutations 传递参数时,必须要在调用该 method 的时候传递参数。

8.模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 修改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: countAbout,
        personAbout: personAbout
      }
    })
    
  3. 开启命名空间后,组件中读取 state 数据:

    //方式一:自己直接读取
    this.$store.state.countAbout.sum
    //方式二:借助mapState生成后再读取:
    ...mapState('countAbout',['sum','school','subject'])
    
  4. 开启命名空间后,组件中读取 getters 数据:

    //方式一:自己直接读取
    this.$store.getters['countAbout/bigSum']
    //方式二:借助mapGetters生成后再读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用 dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions生成后再读取:
    ...mapActions('personAbout',['addPersonWang'])
    
  6. 开启命名空间后,组件中调用 commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations生成后再读取:
    ...mapMutations('personAbout',['ADD_PERSON'])
    

本文章根据尚硅谷笔记整理而成


文章作者: Cubby
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cubby !
  目录