中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue.js中輕松解決v-for執行出錯的三個方案

發布時間:2020-10-07 09:36:19 來源:腳本之家 閱讀:261 作者:王玉豹 欄目:web開發

前言

Vue.js 是開源的一個前端開發庫,通過簡潔的 API 提供高效的數據綁定和靈活的組件系統。在前端紛繁復雜的生態中,Vue.js在近年來受到一定程度的關注,目前在 GitHub上已經有5000+。

本文是筆者在開發實踐中踩過的坑,總結和分享出來,希望對大家學習Vue有所幫助。下面來看看詳細的介紹:

【問題描述】

v-for遍歷數組中存在空值導致頁面報錯,情況如下:

Vue.js中輕松解決v-for執行出錯的三個方案

開發框架是以Vue為模型綁定的核心,根據錯誤可以進行一個簡單的判斷:

      ▪ removeChild操作既然不是發生在開發者顯示書寫的代碼中,就應該是模型銷毀后Vue引擎移除dom節點導致的。

      ▪ 錯誤棧信息都在框架的代碼之內,此操作不可能是有用戶代碼觸發導致的。

開發者某一流程的操作,會100%穩定地觸發出這一錯誤,此錯誤導致js執行終端,整個程序陷入癱瘓無法工作,開發者的操作流程可以簡化為如下的步驟:

      1. 訪問視圖A。

      2. 訪問視圖B。

      3. 回退歷史記錄到A。(錯誤發生在這里)

以上的跳轉關系都是視圖跳轉,也就是發生在路由系統之內的路由跳轉,按照路由邏輯,第三步的時候會依次執行視圖的聲明周期函數,包括:

      ▪ B視圖的unRender邏輯,包括beforeUnRender和afterUnRender。

      ▪ A視圖的Render,包括beforeRender和afterRender。

開發者只在beforeRender的階段進行了模型重置的操作,幾乎可以確定無疑,報錯就是由這幾行模型重置和賦值的操作引起的。層層排除可以尋找到使用簡單代碼重新此問題的方式。

【重現方式】

準備一個簡單的空工程,新建視圖test,一下的代碼分別為js/view/test.js和html/view/test.html,js/view/test.js中視圖對模型的操作可以完整反映重現此問題的流程。其中,setTimeout模擬的是ajax操作以讓數據在多個tick之后設置到模型以觀察Vue對dom節點的創建和銷毀。

$nextTick之后,將test_arr置空的操作是為了使vue將此數據對應的dom節點銷毀,對應代碼如下:

Vue.js中輕松解決v-for執行出錯的三個方案

以上的代碼可以穩定重新問題,下面是解題思路。

【解決方案】

在不求甚解的狀態下,這個問題是比較容易解決的,這里有幾個臨時的解決方案。

▲方案一

從報錯信息Uncaught TypeError: Cannot read property 'removeChild' of null可知,之所以發生這個問題是因為在null的對象上執行了removeChild。

修改Vue框架代碼,將這里的代碼:

Vue.js中輕松解決v-for執行出錯的三個方案

修改為:

Vue.js中輕松解決v-for執行出錯的三個方案

▲方案二

深入地分析,為什么el.parentNode會是null,通過上面重現的步驟發現,當that.model.test_arr = ["","4","","5","6",""]這段代碼設置發生后,v-for產生的dom節點之后3個,而不是5個,這種情況下el.parentNode就是不存在的,所以產生了第二種解決方案,強制不給空數據的元素生成dom節點。

Vue.js中輕松解決v-for執行出錯的三個方案

▲方案三

問題并不算是圓滿解決,正常的情況下框架應該具有魯棒性,適應不同的使用場景,不應該出現js報錯的問題,所以還有深入研究下去的必要。

在Vue中針對v-for指令有一個track-by的可選配置:

       ▪無track-by情況:數據修改時,無論值是否被修改,dom都被重新渲染。

       ▪有track-by情況:數據修改時,不變數據所在的dom不被重新渲染,已改變的數據所在dom才被重新渲染。

因為 v-for 默認通過數據對象的特征來決定對已有作用域和 DOM 元素的復用程度,這可能導致重新渲染整個列表。但是,如果每個對象都有一個唯一 ID 的屬性,便可以使用 track-by 特性給 Vue 一個提示,Vue因而能盡可能地復用已有實例。所以就有了第三種解決方案。


Vue.js中輕松解決v-for執行出錯的三個方案

【原因分析】

v-for遍歷數組中存在空值導致頁面報錯,主要是遍歷條件里對值的判斷有問題。Vue為了保證對dom節點的復用,內置了一份按照id存取的dom緩存,通過對數據分析出dom_id,然后根據此id從緩存中獲取dom節點。由于不同的數據取到了相同的dom_id,所以沒有創建dom節點出來。但是,在最終數組置空,模型變更之后dom節點移除的時候卻為這些dom節點觸發了remove操作,也就是方案一中兼容的那些代碼:

Vue.js中輕松解決v-for執行出錯的三個方案

所以問題必定出現在getTrackByKey這個函數的執行上,以下是getTrackByKey的代碼:

Vue.js中輕松解決v-for執行出錯的三個方案

Vue中對數據綁定的操作大大地提高了開發者應用開發的效率,但與此同時也伴隨著一些不易察覺的問題,尤其如本文中問題的重現條件比較復雜的情況下,測試不一定可以覆蓋到問題的觸發條件,這個時候就需要開發人員多一分警惕。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武强县| 七台河市| 化隆| 那曲县| 宝丰县| 亚东县| 紫云| 林芝县| 革吉县| 濮阳县| 漳州市| 青铜峡市| 丘北县| 黄骅市| 东山县| 临沧市| 丹凤县| 安国市| 晋中市| 稷山县| 邯郸县| 栖霞市| 岑溪市| 桑植县| 莱芜市| 肇源县| 竹山县| 常州市| 白玉县| 萝北县| 南木林县| 夏津县| 普兰店市| 泾川县| 兴城市| 高台县| 宁波市| 康定县| 大理市| 星座| 古田县|