Vuex中的Mutations

本文深入解析Vuex中的Mutations概念,包括状态更新、参数传递、提交风格、响应规则及常量类型的运用,帮助读者掌握Vuex核心机制。

Vuex中的Mutations

一、Mutation状态更新
  1. 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
  2. Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})

这里的 increment就是事件类型,后面跟的函数就是回调函数

  1. 你不能直接调用一个 mutation handler回调函数。这个选项更像是事件注册:“当触发一个类型为 incrementmutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
methods: {
    addition() {
      this.$store.commit('increment')
    }
}
二、Mutation传递参数,也称作提交载荷(Payload)
  1. 在通过mutation更新数据的时候, 有可能我们希望携带一些额外的参数,你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
<button @click="addCount(5)">+5</button>
methods: {
  addCount(count) {
    this.$store.commit('incrementCount', count)
  }
}
mutations: {
  incrementCount(state, count) {
    state.counter += count
  }
}
  1. 但是如果参数不是一个呢?比如我们有很多参数需要传递,这个时候,我们通常会以对象的形式传递, 也就是payload是一个对象,这个时候可以再从对象中取出相关的信息:
methods: {
  addCount(count) {
    this.$store.commit('incrementCount', {count: 5})
  }
}
mutations: {
  incrementCount(state, payload) {
    state.counter += payload.count
  }
}
三、Mutation提交风格
  1. 上面的通过commit进行提交是一种普通的方式
  2. 提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
methods: {
  addCount(count) {
    this.$store.commit({
      type: 'incrementCount',
      count
    })
  }
}
  1. Mutation中的处理方式是将整个commit的对象作为payload使用, 所以代码没有改变, 依然如下:
mutations: {
  incrementCount(state, payload) {
    state.counter += payload.count
  }
}
四、Mutation响应规则
  1. Vuex的store中的state是响应式的, 当state中的数据发生改变时, Vue组件会自动更新.
  2. 这就要求我们必须遵守一些Vuex对应的规则:
    • 提前在store中初始化好所需的属性.
    • 当给state中的对象添加新属性时, 使用下面的方式:
      • 方式一: 使用Vue.set(obj, 'newProp', 123)
      • 方式二: 用新对象给旧对象重新赋值,利用对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }
五、Mutation常量类型
  1. 我们来考虑下面的问题:
    • 在mutation中, 我们定义了很多事件类型(也就是其中的方法名称).
    • 当我们的项目增大时, Vuex管理的状态越来越多, 需要更新状态的情况越来越多, 那么意味着Mutation中的方法越来越多.
    • 方法过多, 使用者需要花费大量的经历去记住这些方法, 甚至是多个文件间来回切换, 查看方法名称, 甚至如果不是复制的时候, 可能还会出现写错的情况.
  2. 如何避免上述的问题呢?
    • 在各种Flux实现中, 一种很常见的方案就是使用常量替代Mutation事件的类型.
    • 我们可以将这些常量放在一个单独的文件中, 方便管理以及让整个app所有的事件类型一目了然.
  3. 具体怎么做呢?
    • 我们可以创建一个文件: mutation-types.js, 并且在其中定义我们的常量.
    • 定义常量时, 我们可以使用ES2015中的风格, 使用一个常量来作为函数的名称.
// mutation-types.js
export const INCREMENT = 'increment'
import Vuex from 'vuex'
import { INCREMENT } from './mutation-types'

const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [INCREMENT] (state) {
      // mutate state
    }
  }
})
六、Mutation同步函数
  1. 通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.
    • 主要的原因是当我们使用devtools时, 可以devtools可以帮助我们捕捉mutation的快照.
    • 但是如果是异步操作, 那么devtools将不能很好的追踪这个操作什么时候会被完成.
  2. 现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在下面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。
mutations: {
  someMutation (state) {
    api.callAsyncMethod(() => {
      state.count++
    })
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值