重新学习vuex---mutation和action区别

首先vuex项目结构需要遵守

Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

应用层级的状态应该集中到单个 store 对象中。

提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

异步逻辑都应该封装到 action 里面。

只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:
在这里插入图片描述

mutation和action区别

基本的vuex操作了解以后,很重要的一点就是要注意mutation和action区别

mutation 是更改状态的唯一方法,并且这个过程是同步的:

mutations: {
    
    
  someMutation (state) {
    
    
    api.callAsyncMethod(() => {
    
    
      state.count++
    })
  }
}

现在想象,我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。

使用常量替代 Mutation 事件类型

使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然:

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import {
    
     SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
    
    
  state: {
    
     ... },
  mutations: {
    
    
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state) {
    
    
      // mutate state
    }
  }
})

用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。

异步逻辑都应该封装到 action 里面

Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

来看一个更加实际的购物车示例,涉及到调用异步 API 和分发多重 mutation:

actions: {
    
    
  checkout ({
    
     commit, state }, products) {
    
    
    // 把当前购物车的物品备份起来
    const savedCartItems = [...state.cart.added]
    // 发出结账请求,然后乐观地清空购物车
    commit(types.CHECKOUT_REQUEST)
    // 购物 API 接受一个成功回调和一个失败回调
    shop.buyProducts(
      products,
      // 成功操作
      () => commit(types.CHECKOUT_SUCCESS),
      // 失败操作
      () => commit(types.CHECKOUT_FAILURE, savedCartItems)
    )
  }
}

我们正在进行一系列的异步操作,并且通过提交 mutation 来记录 action 产生的副作用(即状态变更)。

猜你喜欢

转载自blog.csdn.net/weixin_43902063/article/details/109722365