前端答疑 - v-if 從新渲染致使的 Bug

由於疫情五一假期也不能出去玩,只好在家擼代碼。html

正好昨天排查了一個問題,今天記錄一下。前端

問題

問題是這樣的,有個頁面它裏面有兩個組件 1活動組件、2搜索組件,而後活動組件裏面有個評論留言的功能,測試同窗發現組件切換以後評論被清空了
問題大致就這樣。由於活動不是我作的,我只負責排查問題,因此我也是聽別人的反饋來分析問題。vue

頁面

感興趣的朋友能夠實際下載APP去看一下,VV音樂-首頁輪播圖-五一假期與美同行
以下,切換以後 UI 還在,只是記錄數和評論沒了面試

image.png

基礎條件分析

  1. 單頁面組件切換(不涉及到路由、或者頁面通訊亂七八糟的場景)
  2. 不存在頁面被異常刷新狀況(由於刷新就等於從新打開,從新打開是沒有問題的。)
  3. 評論是公用的一個 js 實現,不是基於 Vue 的。(重點來了緩存

    1. vue 講究的是數據驅動視圖,只要數據在,視圖就ok
    2. js、jQuery 講究的是 DOM,想插節點插節點,節點沒了就沒了。

常見問題排查

到這裏問題已經比較清晰了,Vue 如何使用原生庫。通常來講遇到的問題分爲下面幾個。服務器

  1. 獲取不到 DOM 節點。這裏通常是 nextTick 的問題,由於你操做完數據以後,他並無渲染完畢呢。
  2. 組件開發中獲取 DOM 不方便,有可能出現重複。這裏咱們能夠用 ref 來獲取。
  3. 排序拖動等功能不生效。通常是看上去變了,可是數據不對。由於 jQuery庫的理念就是 DOM 對了就是對了,可是在 Vue 中必需要數據對了,而後數據渲染到頁面。因此處理方式通常是放棄修改 DOM,改成修改數據。

這個 Bug 還比較特殊,不是這裏面的,可是也有關係(和 3 的問題相似)。接來下出道面試題吧微信

v-if 和 v-show 的區別

這面試題不陌生吧,想必你們也有答案。函數

v-if

v-if 根據表達式的值的來有條件地渲染元素。採用組件銷燬、重建的方式。測試

若是一開始就是 false,那麼這個組件不會被建立(生命週期鉤子函數不會被調用)。spa

若是一開始是 true,而後改成 false,這個時候組件會被銷燬(destory 等生命週期鉤子函數都會執行)。以後若是再改成 true,那麼會從新建立(created 等鉤子函數會執行)。

v-show

v-show 根據表達式的值的來有條件地渲染元素。是經過設置元素的 display CSS 屬性來實現渲染效果。

無論是 true 仍是 false 都會渲染出組件。只不過爲 falsedisplay:none

解決問題

基於上面的分析咱們知道了,由於 v-if 致使組件被銷燬,而後再次渲染的時候是根據 Vue 中的數據來渲染的,並無 DOM 數據。

解決方案一:v-show

既然 v-show 不會銷燬,那麼咱們能夠緩存 v-show

這個方案的缺點

  1. 組件在一開始初始化的時候就所有被渲染了。會存在大量請求、無效數據打倒服務器。
  2. 由於他在一開始就渲染了,因此若是你沒有加載完數據的話,存在報錯的可能性。list && list.length 少不了這種代碼的存在

解決方案二:切換以後再調用一次

既然 created 的時候是好的,那麼咱們切換以後再次調用一下初始化渲染不就能夠了。

這個方案的缺點

  1. 由於存在二次渲染,jQuery 等插件通常都會監聽事件。因此須要注意事件不能被屢次觸發。
  2. 仍是由於上個問題,也要注意由於事件引用等問題致使的內存泄漏。

測試DEMO

https://www.lilnong.top/stati...

補一下 DEMO,能夠看到一進去四個 input 都是有內容的。

切換以後 v-if 下面的input就有個丟值了。而 v-show 的不受影響。

增長 keep-alive 和組件測試

能夠先在 keep-alive 組件中填入內容,而後切換,發現 v-if 的數據沒有了
image.png

微信公衆號:前端linong

歡迎你們關注個人公衆號。有疑問也能夠加個人微信前端交流羣。
clipboard.png

相關文章
相關標籤/搜索