1. 程式人生 > >Vue 專案開發之疑難雜症

Vue 專案開發之疑難雜症

1、使用v-model 繫結物件的動態屬性,導致v-model失效或者資料異常

 場景:使用iview的CheckboxGroup 做checkbox多選時,發現勾選的選項和v-model繫結物件對應的屬性值不匹配。

template程式碼如下:

<CheckboxGroup v-else-if="item.formType === 'checkbox'" v-model="metaTemplate[item.name]">
        <Checkbox v-for="(check, index) in JSON.parse(item.formValue)" :key="index" :label="check"></Checkbox>
 </CheckboxGroup>

這裡面checkbox的值和個數都是通過介面返回動態引數決定的,v-model繫結到一個叫meteTemplate物件的屬性上,而這個屬性也是動態新增上去的。怪異的問題是:假設現在checkbox有三個,當全部選中三個時,這時候預期的結果是繫結的物件屬性是一個含有三個值的陣列,但實際是含有一個值的陣列,看起來感覺v-model出現問題了,即UI變化沒有反應到資料上。

template物件定義如下:

 data () {
    return {
      metaTemplate: {
      }
  },

它是一個簡單的空物件,物件屬性是動態加上去的,錯誤截圖如下:

這裡看到UI的狀態和資料並不保持一致,感覺很怪異。

嘗試辦法:

(1) 重新定義一個屬性使用v-model和checkbox繫結,發現正常工作。

 (2)在metaTemplate中預選定義一個屬性,例如metaTemplate{checkArr:[]}, 發現頁正常工作。

思考:

   從上面的嘗試辦法看出不是元件本身的問題,不是物件屬性巢狀的問題,這次最大的不同就是繫結的屬性是後來加到物件上去的,即v-model是物件的一個動態屬性,於是就思考動態屬性是不是需要特殊處理後才能適用於v-model?

解決辦法:

原因:

見Vue.js中文官網->進階->深入響應式原理->變化檢測問題

受現代 JavaScript 的限制(以及廢棄 Object.observe),Vue 不能檢測到物件屬性的新增或刪除。由於 Vue 會在初始化例項時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 物件上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。例如:

方案:

1、使用 Vue.set(object, key, value) 方法將響應屬性新增到巢狀的物件上:

Vue.set(vm.someObject, 'b', 2) 2、您還可以使用 vm.$set 例項方法,這也是全域性 Vue.set 方法的別名:

   this.$set(this.someObject,'b',2) 3、使用 Object.assign() 或 _.extend() 方法來新增屬性

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

例項解決辦法:

this.$set(this.metaTemplate, item.name, [])

2、iview表單驗證規則遇到非string型別時,如果不明確指明型別,則可能驗證失敗

  場景:很多表單項都需要驗證是否為空,現有一項表單為多選的checkbox繫結的值,最終資料應該是一個數組,驗證規則如下:

 { required: true, message: '請輸入該欄位', trigger: 'blur' }

但勾選了選項後,點選確認提交表單,發現表單驗證不通過,在checkbox下面提示:‘請輸入該欄位’。

思考:明顯是驗證規則有問題,發現沒有明確指定驗證的type型別。

解決辦法

{ required: true, type: 'array', message: '請輸入該欄位', trigger: 'blur' }