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後的狀態

相關文章
相關標籤/搜索