欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue.js中輕松解決v-for執(zhí)行出錯(cuò)的三個(gè)方案

 更新時(shí)間:2017年06月09日 09:04:51   作者:王玉豹  
v-for標(biāo)簽可以用來(lái)遍歷數(shù)組,將數(shù)組的每一個(gè)值綁定到相應(yīng)的視圖元素中去,下面這篇文章主要給大家介紹了關(guān)于在Vue.js中輕松解決v-for執(zhí)行出錯(cuò)的三個(gè)方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。

前言

Vue.js 是開(kāi)源的一個(gè)前端開(kāi)發(fā)庫(kù),通過(guò)簡(jiǎn)潔的 API 提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng)。在前端紛繁復(fù)雜的生態(tài)中,Vue.js在近年來(lái)受到一定程度的關(guān)注,目前在 GitHub上已經(jīng)有5000+。

本文是筆者在開(kāi)發(fā)實(shí)踐中踩過(guò)的坑,總結(jié)和分享出來(lái),希望對(duì)大家學(xué)習(xí)Vue有所幫助。下面來(lái)看看詳細(xì)的介紹:

【問(wèn)題描述】

v-for遍歷數(shù)組中存在空值導(dǎo)致頁(yè)面報(bào)錯(cuò),情況如下:

開(kāi)發(fā)框架是以Vue為模型綁定的核心,根據(jù)錯(cuò)誤可以進(jìn)行一個(gè)簡(jiǎn)單的判斷:

      ▪ removeChild操作既然不是發(fā)生在開(kāi)發(fā)者顯示書(shū)寫(xiě)的代碼中,就應(yīng)該是模型銷(xiāo)毀后Vue引擎移除dom節(jié)點(diǎn)導(dǎo)致的。

      ▪ 錯(cuò)誤棧信息都在框架的代碼之內(nèi),此操作不可能是有用戶代碼觸發(fā)導(dǎo)致的。

開(kāi)發(fā)者某一流程的操作,會(huì)100%穩(wěn)定地觸發(fā)出這一錯(cuò)誤,此錯(cuò)誤導(dǎo)致js執(zhí)行終端,整個(gè)程序陷入癱瘓無(wú)法工作,開(kāi)發(fā)者的操作流程可以簡(jiǎn)化為如下的步驟:

      1. 訪問(wèn)視圖A。

      2. 訪問(wèn)視圖B。

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

以上的跳轉(zhuǎn)關(guān)系都是視圖跳轉(zhuǎn),也就是發(fā)生在路由系統(tǒng)之內(nèi)的路由跳轉(zhuǎn),按照路由邏輯,第三步的時(shí)候會(huì)依次執(zhí)行視圖的聲明周期函數(shù),包括:

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

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

開(kāi)發(fā)者只在beforeRender的階段進(jìn)行了模型重置的操作,幾乎可以確定無(wú)疑,報(bào)錯(cuò)就是由這幾行模型重置和賦值的操作引起的。層層排除可以尋找到使用簡(jiǎn)單代碼重新此問(wèn)題的方式。

【重現(xiàn)方式】

準(zhǔn)備一個(gè)簡(jiǎn)單的空工程,新建視圖test,一下的代碼分別為js/view/test.js和html/view/test.html,js/view/test.js中視圖對(duì)模型的操作可以完整反映重現(xiàn)此問(wèn)題的流程。其中,setTimeout模擬的是ajax操作以讓數(shù)據(jù)在多個(gè)tick之后設(shè)置到模型以觀察Vue對(duì)dom節(jié)點(diǎn)的創(chuàng)建和銷(xiāo)毀。

$nextTick之后,將test_arr置空的操作是為了使vue將此數(shù)據(jù)對(duì)應(yīng)的dom節(jié)點(diǎn)銷(xiāo)毀,對(duì)應(yīng)代碼如下:

以上的代碼可以穩(wěn)定重新問(wèn)題,下面是解題思路。

【解決方案】

在不求甚解的狀態(tài)下,這個(gè)問(wèn)題是比較容易解決的,這里有幾個(gè)臨時(shí)的解決方案。

▲方案一

從報(bào)錯(cuò)信息Uncaught TypeError: Cannot read property 'removeChild' of null可知,之所以發(fā)生這個(gè)問(wèn)題是因?yàn)樵趎ull的對(duì)象上執(zhí)行了removeChild。

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

修改為:


▲方案二

深入地分析,為什么el.parentNode會(huì)是null,通過(guò)上面重現(xiàn)的步驟發(fā)現(xiàn),當(dāng)that.model.test_arr = ["","4","","5","6",""]這段代碼設(shè)置發(fā)生后,v-for產(chǎn)生的dom節(jié)點(diǎn)之后3個(gè),而不是5個(gè),這種情況下el.parentNode就是不存在的,所以產(chǎn)生了第二種解決方案,強(qiáng)制不給空數(shù)據(jù)的元素生成dom節(jié)點(diǎn)。


▲方案三

問(wèn)題并不算是圓滿解決,正常的情況下框架應(yīng)該具有魯棒性,適應(yīng)不同的使用場(chǎng)景,不應(yīng)該出現(xiàn)js報(bào)錯(cuò)的問(wèn)題,所以還有深入研究下去的必要。

在Vue中針對(duì)v-for指令有一個(gè)track-by的可選配置:

       ▪無(wú)track-by情況:數(shù)據(jù)修改時(shí),無(wú)論值是否被修改,dom都被重新渲染。

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

因?yàn)?v-for 默認(rèn)通過(guò)數(shù)據(jù)對(duì)象的特征來(lái)決定對(duì)已有作用域和 DOM 元素的復(fù)用程度,這可能導(dǎo)致重新渲染整個(gè)列表。但是,如果每個(gè)對(duì)象都有一個(gè)唯一 ID 的屬性,便可以使用 track-by 特性給 Vue 一個(gè)提示,Vue因而能盡可能地復(fù)用已有實(shí)例。所以就有了第三種解決方案。


【原因分析】

v-for遍歷數(shù)組中存在空值導(dǎo)致頁(yè)面報(bào)錯(cuò),主要是遍歷條件里對(duì)值的判斷有問(wèn)題。Vue為了保證對(duì)dom節(jié)點(diǎn)的復(fù)用,內(nèi)置了一份按照id存取的dom緩存,通過(guò)對(duì)數(shù)據(jù)分析出dom_id,然后根據(jù)此id從緩存中獲取dom節(jié)點(diǎn)。由于不同的數(shù)據(jù)取到了相同的dom_id,所以沒(méi)有創(chuàng)建dom節(jié)點(diǎn)出來(lái)。但是,在最終數(shù)組置空,模型變更之后dom節(jié)點(diǎn)移除的時(shí)候卻為這些dom節(jié)點(diǎn)觸發(fā)了remove操作,也就是方案一中兼容的那些代碼:


所以問(wèn)題必定出現(xiàn)在getTrackByKey這個(gè)函數(shù)的執(zhí)行上,以下是getTrackByKey的代碼:


Vue中對(duì)數(shù)據(jù)綁定的操作大大地提高了開(kāi)發(fā)者應(yīng)用開(kāi)發(fā)的效率,但與此同時(shí)也伴隨著一些不易察覺(jué)的問(wèn)題,尤其如本文中問(wèn)題的重現(xiàn)條件比較復(fù)雜的情況下,測(cè)試不一定可以覆蓋到問(wèn)題的觸發(fā)條件,這個(gè)時(shí)候就需要開(kāi)發(fā)人員多一分警惕。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Vue生命周期與setup深入詳解

    Vue生命周期與setup深入詳解

    Vue的生命周期就是vue實(shí)例從創(chuàng)建到銷(xiāo)毀的全過(guò)程,也就是new Vue() 開(kāi)始就是vue生命周期的開(kāi)始。Vue 實(shí)例有?個(gè)完整的?命周期,也就是從開(kāi)始創(chuàng)建、初始化數(shù)據(jù)、編譯模版、掛載Dom -> 渲染、更新 -> 渲染、卸載 等?系列過(guò)程,稱這是Vue的?命周期
    2022-09-09
  • 如何使用Webpack優(yōu)化Vue項(xiàng)目的打包流程

    如何使用Webpack優(yōu)化Vue項(xiàng)目的打包流程

    在開(kāi)發(fā)基于Vue.js的應(yīng)用時(shí),隨著項(xiàng)目規(guī)模的擴(kuò)大,單個(gè)文件的體積也會(huì)隨之增長(zhǎng),特別是當(dāng)涉及到大量的依賴庫(kù)和復(fù)雜的業(yè)務(wù)邏輯時(shí),本文將詳細(xì)介紹如何使用Webpack來(lái)優(yōu)化Vue項(xiàng)目的打包流程,需要的朋友可以參考下
    2024-09-09
  • Vue組件和Route的生命周期實(shí)例詳解

    Vue組件和Route的生命周期實(shí)例詳解

    這篇文章主要介紹了Vue組件和Route的生命周期的相關(guān)知識(shí),需要的朋友可以參考下
    2018-02-02
  • Vue中ElementUI分頁(yè)組件Pagination的使用方法

    Vue中ElementUI分頁(yè)組件Pagination的使用方法

    這篇文章主要為大家詳細(xì)介紹了Vue中ElementUI分頁(yè)組件Pagination的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Element Plus實(shí)現(xiàn)Affix 固釘

    Element Plus實(shí)現(xiàn)Affix 固釘

    本文主要介紹了Element Plus實(shí)現(xiàn)Affix 固釘,Affix組件用于將頁(yè)面元素固定在特定可視區(qū)域,文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下
    2021-07-07
  • vue.config.js文件devServer字段的常用選項(xiàng)詳解

    vue.config.js文件devServer字段的常用選項(xiàng)詳解

    在?Vue?CLI?生成的?vue.config.js?文件中,devServer?字段用于配置開(kāi)發(fā)服務(wù)器的選項(xiàng),本文給大家介紹vue.config.js文件devServer字段的常用選項(xiàng),感興趣的朋友一起看看吧
    2023-11-11
  • 詳解 vue.js用法和特性

    詳解 vue.js用法和特性

    Vue.js目前已經(jīng)更新到2.x,功能和語(yǔ)法上有一定升級(jí)和修改,本文首先介紹基礎(chǔ)內(nèi)容。感興趣的朋友一起看看吧
    2017-10-10
  • 詳解vue-cli3使用

    詳解vue-cli3使用

    這篇文章主要介紹了詳解vue/cli 3使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Vue.js每天必學(xué)之過(guò)渡與動(dòng)畫(huà)

    Vue.js每天必學(xué)之過(guò)渡與動(dòng)畫(huà)

    Vue.js每天必學(xué)之過(guò)渡與動(dòng)畫(huà),對(duì)Vue.js過(guò)渡與動(dòng)畫(huà)進(jìn)行深入學(xué)習(xí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • vue2.0 根據(jù)狀態(tài)值進(jìn)行樣式的改變展示方法

    vue2.0 根據(jù)狀態(tài)值進(jìn)行樣式的改變展示方法

    下面小編就為大家分享一篇vue2.0 根據(jù)狀態(tài)值進(jìn)行樣式的改變展示方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03

最新評(píng)論