使用Vue自定義組件時需要注意在那個生命週期中初始化組件
有這樣一個業務需求:
- 頁面中包含兩個div, 兩個div通過選擇radio切換顯示
- div的顯示通過v-if控制
- 每個div中都包含一個自定義select組件
- 兩個select組件中的list不一樣
頁面完成夠發現兩個div中的select組件都可正常下拉\選擇值, 但是當在div a中的select選擇了值後, 比如選擇value a, 再通過radio切換到div b, 發現div b中的select上顯示div a中選擇的值value a, 而value a不存在與div b中的select的data list中.
初步估計是select組件中顯示的label從上一個vue實例中緩存了下來, 在mounted鉤子中沒能過濾掉這個這個值.
打印出來看看:
發現在mounted狀態中組件中顯示的label, 即截圖中的selectShow爲空, 因此不能被過濾掉. updated狀態selectShow的值就出現了, 這時獲得了selectShow值的引用我們就可以過濾掉上一個vue實例的selectShow的值了.
但是, updated狀態我們的組件已經更新完成, 就是說組件已經完成顯示了, 已經顯示在我們的屏幕上了, 這時再去過濾值就會引起屬性的更新, vue就會再走一遍生命週期的流程, 這是一個死循環, 在更新完成狀態updated中開始新更新, 會導致瀏覽器卡死.
那麼, 我們應該在哪裏進行數據過濾呢?
除了updated狀態外, 還有一個生命週期能獲得selectShow的引用, 並且不會導致死循環.
這就是beforeUpdate, 在beforeUpdate中我們可以放心的進行數據過濾, 例如直接將selectShow置空.
出現這種問題的原因編寫組件時對vue的生命週期不夠了解, 通常只在mounted中進行前置操作, 沒有考慮到屬性在vue實例的不同生命週期的不同狀態.