Vuex 基础解析

78 阅读3分钟

理解 vuex

vuex 的定义

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

Vuex 原理

企业微信截图_16428317819760.png

搭建 Vuex 开发环境

  • 下载 Vuex
  • 引入并使用 Vuex vue.use(Vuex)
  • 传入 stroe 配置项

配置 stroe 文件

企业微信截图_16428309463647.png

  • 此时,vm 和所有的组件都可以调用 $store,它包含了操作数据所需要的所有 api

使用 vuex 重构一个小案例

先来看一个实现各种简单计算的 vue 组件

企业微信截图_1642832170702.png

  • 一个标题用来显示当前的计算结果
  • 左边一个 select 选择框,用来指定每次计算用到的数值;四个按钮功能分别为加法、减法、当前计算结果为奇数时再做加法,以及等一秒钟之后再做加法

代码如下

企业微信截图_16428324048760.png

现在我们从模型图中的 state 出发,开始改造

  1. 将最终要显示的数据(sum)交给state

  2. 从第一个按钮的函数里,调用 dispatch,告诉 actions,接下来要执行的操作(add),并且将执行操作需要的数据(this.number)传递过去

    企业微信截图_16428338318617.png

  3. 在 store 文件中的 actions 里面,定义执行操作的 add 函数,函数可以接收两个参数,第一个是一个精简的 $store,它包含了 dispatchcommit 等 api;第二个参数为执行操作需要的数据(this.number)。并在 add 函数里调用 commit

    企业微信截图_16428344533053.png

  4. ADD 大写是为了区分 actions 和 mutations 里的 add

至此,actions 的任务完成,进入 mutations

  1. 在 mutations 中定义 ADD 函数,函数可以接收两个参数,第一个为存储数据用的 state,第二个为执行操作需要的数据(this.number)

    企业微信截图_16428349905073.png

然后在组件中读取 state 中的数据,整个流程结束,其他三个功能同理

企业微信截图_16428352286230.png

  • 有一点值得一提,就是所有的业务逻辑(包括 Ajax 请求),都应该放在 actions 里面。所以代码改造后的奇数判断定时器,都应该在 actions 里面,代码如下

企业微信截图_16428374179606.png

企业微信截图_16428374751419.png

完善

  • 以上说过,actions 里面是处理业务逻辑的,那么开始定义的两个函数: addsub就显得很多余,因为它不包含任何的业务逻辑。对于这种情况,vuex 支持直接从组件中对话 mutations,跳过 actions

    企业微信截图_16428379446095.png

vuex 中的 getters

  • 该配置项用来对 state 中的数据进行加工,以供其他组件复用

  • getters 中可以直接定义函数,函数的参数为 state,并以返回值来获得函数的执行结果

  • 我们将以上案例增加一个功能,即可以显示最终计算结果再乘以十的结果

    1. 在组件的模板中增加一个三级标题用来显示乘以十的结果

    2. 配置 getters,并定义一个使结果乘以 10 的函数

      企业微信截图_16428398648835.png

    3. 在组件的模板中通过 $store 获得 getters 中的返回值

企业微信截图_16428399527248.png

代码优化

  • 解决模板在获取数据时,代码过长的问题
    • 在获取 state 中的数据 sum 时,模板中使用了$store.state.sum,我们可以通过使用计算属性 computed 来实现在模板中只用写 sum就可以获取数据

      企业微信截图_16430078806925.png

    • 这样很方便,但如果 state 中还有其他更多的数据需要获取,那就要重复定义更多个 computed,代码依然冗余。所以 vuex 提供了mapState来生成这些计算属性。

    • mapState 的返回值是一个包含了一个或多个 computed 函数的对象。我们需要将要定义的函数名,以及要获取的数据,以对象的形式通过参数传递给它。它就可以帮我们生成 computed 函数

      企业微信截图_16430085069123.png

    • 当我们需要生成的函数的函数名和要获取数据的变量名相同时,mapState还可以写成数组的格式,它看起来会更简洁

      企业微信截图_16430087041133.png

    • 同样的,vuex 也提供了用于从 getters 里面获取数据的mapGetters,使用方法和mapState一样,最终代码改造是这样的

      企业微信截图_16430088722452.png

  • methods 代码优化
    • mapMutationsmapActions
    • mapMutations用来生成调用 commit 的方法,mapActions用来生成调用 dispatch 的方法
    • 用法和 mapState 大同小异,将要生成的函数名和要调用的函数名当作参数以对象的方式传递
    • 经过改造的 methods 最终代码为
    企业微信截图_164301044196.png
    • 同样的,mapMutationsmapActions也有数组的写法
    • 要执行操作的数据,要在模板绑定事件时以参数的方式传递
    • 最终完成的代码
    企业微信截图_1643010539374.png