Vue 全家桶之一

官网

统一更新 state 的全局方法

mutation 的定义比较迷…
个人喜欢不管是不是异步逻辑,都放在 action 中处理,然后提交 mutation
但是如果一个 state 就定义一个 mutation 方法,就太累了
这里记录定义一个统一的方法
PS:基于 lodash 的 set 方法实现

// 定义在全局,通过路径的方式可以直接修改子模块的 state
new Vuex.Store({
  mutations: {
    /**
     *  全局统一更新 state 的方法
     *
     *  @requires lodash
     *
     *  @param { Object | Array } payload
     *
     *  @param { String } [payload.path] - 要修改的字段路径
     *  @param { String } payload[].path - 要修改的字段路径
     *
     *  @param { Any } [payload.value] - 要修改的字段值
     *  @param { Any } payload[].value - 要修改的字段值
     *
     *  @param { String } [payload.comment] - 提交 mutation 的备注,仅为了 vue-devtool 方便测试,无实际用途
     *  @param { String } [payload[].comment] - 提交 mutation 的备注,仅为了 vue-devtool 方便测试,无实际用途
     **/
    UPDATE_STATE: function (state, payload) {
      var arr = [].concat(payload)
      
      arr.forEach(function (item) {
        var path = item.path
        var value = item.value
        
        if (!path) {
          throw new Error('来自 vuex mutation UPDATE_VALUE 的报错:path 不能为空')
        }
        
        _.set(state, path, value)
      })
    }
  }
})
// 使用

this.$store.commit('UPDATE_STATE', {
  path: 'arr[0][0][0].test',
  value: new Date().getTime(),
  comment: '我是备注'
})

// or

this.$store.commit('UPDATE_STATE', [
  {
    path: 'test',
    value: new Date().getTime()
  },
  {
    path: 'obj.obj.test',
    value: new Date().getTime()
  },
  {
    path: 'arr[0][0][0].test',
    value: new Date().getTime()
  }
])

// 如果是在 modules 里 namespaced 为 true 的情况下
// 在 actions 里提交 mutation
// 需要在 commit 方法的第三个参数里设置 root: true
new Vuex.Store({
  modules: {
    any: {
      namespaced: true,
      actions: {
        handler: function (context) {
          context.commit('UPDATE_STATE', {
            path: 'any.any',
            value: 10086
          }, { root: true })
        }
      }
    }
  }
})