Vuex 严格模式下 form表单处理 比官网更好的办法

Vuex form表单处理 比官网更好的办法

问题, 当使用vuex的state做为表单的v-model元素, 虽然简单粗暴, 但这种修改没有通过mutation方法. 在严格模式下会抛出错误vue

1. 错误提示

错误代码以下es6

[Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."vuex


2. 相关场景

vuex中相关代码ide

const state = ()=>({
  user: {
    username: '123',
    password: '123',
  }
});

const getters = {
  userName: state=>state.userName,
  user: state=>state.user,
};

const mutations = {
  changeObject(state, payload){
    // es6语法
    state.user = {...state.user, ...payload};
  },
};

其中定义了user变量this


组件中相关代码双向绑定

// 获取vuex中user
...mapGetters('module1', [
    'user',
]),
// 改变vuex中user状态
...mapMutations('module1', [
    'changeObject',
]),

3. 官网建议方法

  • <input> 中绑定 value,而后侦听 input 或者 change 事件,在事件回调中调用一个方法
  • 另外一个方法是使用带有 setter 的双向绑定计算属性
// ...
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

这两种方法都有一种很大的缺陷, 必须定义每一个输入元素的变量, 好比, 如今有个表单, 里面有20个元素, 那么此时就要写20个方法来响应输入框的变化, 做为工匠人, 不得不采起更好的办法代理



4. 解决方案

我的在网上找了一些解决方案, 有用proxy代理, 有封装一些方法的, 这些在我看来, 都挺勉强的code

通过一系列尝试, 我改良了官网描述的第二种方法, 将表单元素与vuex双向绑定, 而且通过了mutation, 严格模式下不报错orm

核心代码以下对象

定义表单对象

// 定义在computed下
object: {
 set(val){
   // console.log(val);
   this.changeObject(val);
 },
  //这里须要注意, 获取的是user信息, 并不是对象, 采用扩展运算符处理
  get(){
   return {...this.user}
  }
}

获取表单变化代码

<form :model="object" @input="inputChange">
  <input type="text" v-model="object.username">
  <input type="text" v-model="object.password">
</form>

// ... methods中方法
inputChange(){
  this.object = {...this.object}
},


5. 总体解释

  1. vuex定义username和password
  2. object 经过 get 获取到username和password进行初始化
  3. 表单输入触发inputChange方法改变 object 对象, 触发object对象的 set 方法
  4. object的 set 方法改变了 vuex中的值
  5. vuex 值发生改变, 从而触发 object 的 get 方法
  6. object值发生改变, 从而造成一个循环链

  1. 初始状态

  1. 改变username后的状态

image-20201125204440609

  1. 改变password后的状态

相关文章
相关标签/搜索