Skip to content

vuex中mutations为什么要写成同步方法

首先说明:你要写成异步也可以,没人拦着你,除了调试(状态无法追踪)有点问题,其他暂无发现。

为什么要同步?

  • 原因: 使用devtools调试的时候会有问题。就是这么一句话,简单粗暴?有其他原因请留言狠狠的打脸,感恩大佬。

有什么问题?

  • 调试环境下:使用setTimeout模仿异步,注意看mutations里面的代码:
js
import Vue from 'vue'

import Vuex from 'vuex'

Vue.use(Vuex)

let Store = new Vuex.Store({

  state: { // 仓库

    userInfo: {

      name: 'Test'

    }

  },

  getters: { // 监听state里面某个属性的变化,类似computed属性

    getUserInfo (state) {

      // state.userInfo.name = 666 // 不能在此改变state中的数据,不会报错,但是无效

      return state.userInfo

    }

  },

  // // 只能在这里才能改变state里面的数据,mutations必须是同步函数。原因是在mutation中混合异步调用会导致程序很难调试。用devtools很难追踪状态的改变。所以就定义了一个actions专门进行异步的处理。

  mutations: {

    handleUserName (state, newValue) {

      setTimeout(() => {

        state.userInfo.name = newValue

      }, 1000)

    }

  },

  actions: {

    changeUserName (context, newValue) { // context: 上下文

      setTimeout(() => {

        console.log(context, newValue)

        context.commit('handleUserName', newValue)

      }, 1000)

    }

  }

})

export default Store

此时commit一个handleUserName尝试下会发生什么?

image

点击后

image

为什么state未改变?

  • 原因是在mutation中混合异步调用会导致程序很难调试。用devtools很难追踪状态的改变。所以就定义了一个actions专门进行异步的处理。

将mutations中的代码改成同步方法再测试下

js

  mutations: {

    handleUserName (state, newValue) {

      // setTimeout(() => {

        state.userInfo.name = newValue

      // }, 1000)

    }

  }

image

mutations必须同步的原因是状态追踪,你写在action、getter都是可以的,只是不规范的问题。

ps:Vuex可配置为strict模式来规范开发