(一)iview的校驗TypeError: Cannot read property 'validateField' of undefined"
一、問題描述
我是在自己封裝了一個地址級聯選擇,然後想要每次改變了其中資料的時候,就進行一次單獨校驗,所以用到了iview對部分表單欄位進行校驗的方法validateField。其實一開始使用的時候是沒有任何問題的,問題出現的原因是我有多個表單,每次只顯示一個表單,可以來回切換,如下圖。我使用的是v-if來控制表單2和表單3的顯示與隱藏,在我填完資訊2以後進入到資訊3,然後再點選回去資訊2的時候,便報錯了:TypeError: Cannot read property 'validateField' of undefined"
二、問題關鍵
我就很奇怪為什麼我一開始的校驗是好的,返回來此表單就會出錯呢,這對單個表單校驗出錯也太坑了吧。然後我列印了this.$refs.['formTwo']發現列印的是undefined,也就是說根本就不是表單校驗出了問題,而是在於壓根就找不到這個DOM物件。
關鍵點在於,Vue 在更新 DOM 時是非同步執行的,而我我使用了v-if來控制所有表單內容的顯隱,而v-if它通過動態的摧毀DOM又構建,來控制元素的顯隱。在我重新切回表單2的時候,原來的DOM早已被摧毀,此時又還未建立完成。
三、解決辦法
1、我想到的第一個辦法是使用v-show;v-if是通過控制dom節點的存在與否來控制元素的顯隱;v-show是通過控制DOM元素的display樣式來到達顯隱,之前在寫富文字編輯切換的時候也出現什麼東西undefined,錯誤同樣的原因也是我使用了v-if來控制每一個富文字編輯,後來改為v-show之後,解決了問題。
而在這個地方,這樣改隨之而來的另一個問題是我所有的表單在一開始的時候都出現了,我知道這肯定是和我的判斷條件寫的不對有關,可我又不想改,於是有了第二個解決方法。
2、使用nextTick。為了在資料變化之後等待 Vue 完成更新 DOM,可以在資料變化之後立即使用 Vue.nextTick(callback)
。這樣回撥函式將在 DOM 更新完成後被呼叫。於是我將該句單獨校驗表單的程式碼寫在了裡面,問題解決~ 如下:
this.$nextTick(() => { this.$refs.['formTwo'].validateField('street') });
四、相關知識點
v-if和v-show的區別(使用v-if的時候一定要好好考慮清楚!)
vue非同步載入dom(參考:https://cn.vuejs.org/v2/guide/reactivity.html)
如何單獨校驗某一表單項
&n