最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue中key使用的問(wèn)題示例解析

 更新時(shí)間:2022年11月28日 15:47:12   作者:空山與新雨  
這篇文章主要為大家介紹了vue中key使用的問(wèn)題示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在vue要求在遍歷的時(shí)候最好加上key,在使用過(guò)程中總有些疑問(wèn),在這里做下分析

不使用key的時(shí)候vue是怎么處理的

在vue2.x文檔中有如下描述

key 的特殊 attribute 主要用在 Vue 的虛擬 DOM 算法,在新舊 nodes 對(duì)比時(shí)辨識(shí) VNodes。如果不使用 key,Vue 會(huì)使用一種最大限度減少動(dòng)態(tài)元素并且盡可能的嘗試就地修改/復(fù)用相同類型元素的算法。而使用 key 時(shí),它會(huì)基于 key 的變化重新排列元素順序,并且會(huì)移除 key 不存在的元素。

在這段話中提到不使用key的時(shí)候,會(huì)盡量原地復(fù)用,復(fù)用的判斷依據(jù)是常常在面試中被問(wèn)到的sameVnode這個(gè)方法:

function sameVnode (a, b) {
  return (
    // 因?yàn)闆](méi)有定義key,可以得知a.key和b.key都是undefined,進(jìn)而后面的條件進(jìn)行判斷;
    a.key === b.key && (
      (
        a.tag === b.tag &&
        a.isComment === b.isComment &&
        isDef(a.data) === isDef(b.data) &&
        sameInputType(a, b)
      ) || (
        isTrue(a.isAsyncPlaceholder) &&
        a.asyncFactory === b.asyncFactory &&
        isUndef(b.asyncFactory.error)
      )
    )
  )
}

使用key一定能提高diff效率么

答案是并不是,可以看下面的例子

<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
<div id="app">
  <div class="ttt" v-for="(item) in list">{{item}}</div>
  <button @click="changeData">更新</button>
</div>
<script >
  new Vue({
    el: '#app',
    data() {
      return {
        list: [1, 2, 3]
      }
    },
    mounted(){
      Array.from(document.querySelectorAll('.ttt')).forEach(item=>{
        item.dataset.mm = item.textContent;
      })
    },
    methods:{
      changeData(){
        this.list = [4, 5, 6]
      }
    }
  })
</script>

初始dom結(jié)構(gòu)如下:

沒(méi)有key情況下更新數(shù)組,然后DOM結(jié)構(gòu)如下,可以看到dataset值沒(méi)有變化,可以初步判斷只是更新了div的內(nèi)容

使用數(shù)組元素作為key情況下更新數(shù)組,然后DOM結(jié)構(gòu)如下,可以看到dataset沒(méi)有了,可以初步判斷刪除和創(chuàng)建了新的dom,很明顯這樣處理效率更低。

vue源碼中的處理程序邏輯:
沒(méi)有key的情況: updateChildren -> 判定為同類型節(jié)點(diǎn)(div),執(zhí)行patchVnode方法 -> 再對(duì)div這個(gè)節(jié)點(diǎn)做updateChildren處理 -> 繼續(xù)patchVnode,最后的結(jié)果就是更新文本節(jié)點(diǎn)內(nèi)容;

if (oldVnode.text !== vnode.text) {
  nodeOps.setTextContent(elm, vnode.text)
}

有key并且key不相等: updateChildren -> key不同,判定不同類型節(jié)點(diǎn)(div),執(zhí)行createElm方法,進(jìn)而創(chuàng)建新的dom節(jié)點(diǎn);

為什么說(shuō)使用index作為key容易出錯(cuò)

  • 復(fù)現(xiàn)步驟:在第一行的Input里輸入1,在第二行Input里輸入2,然后點(diǎn)第一行的“ד刪除第一行
  • 期待結(jié)果:刪除第一行后,應(yīng)該變成“dog:2”
  • 實(shí)際結(jié)果:刪除第一行后,變成了“dog:1”
<script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
<div id="app">
  <ul>
    <li v-for="(item, index) in list" :key="index">
      <test-row :name="item"></test-row>
      <span style="color: red;cursor: pointer" @click="handleRemove(index)">X</span>
    </li>
  </ul>
</div>
<script>
  Vue.component('test-row', {
    template: `<span>
      <span>{{ name }}:</span>
      <input v-model="nums"/>
      </span>`,
    props: {
      name: String
    },
    data() {
      return {
        nums: ''
      }
    }
  })
  new Vue({
    el: '#app',
    data() {
      return {
        list: ['cat', 'dog']
      }
    },
    methods: {
      handleRemove(i) {
        this.list.splice(i, 1);
      }
    }
  })
</script>

出現(xiàn)問(wèn)題的原因:在patch階段會(huì)認(rèn)為這兩個(gè)input子節(jié)點(diǎn)是sameVnode,進(jìn)而復(fù)用原來(lái)的dom節(jié)點(diǎn),因?yàn)榻M件只觸發(fā)了更新,沒(méi)有重新創(chuàng)建實(shí)例, 所以組件實(shí)例data數(shù)據(jù)沒(méi)有變化,輸入框內(nèi)的內(nèi)容就不會(huì)變化。

如果使用dog、cat作為key就可以避免這個(gè)bug;

以上就是vue中key使用的問(wèn)題示例解析的詳細(xì)內(nèi)容,更多關(guān)于vue key使用問(wèn)題的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3中使用vuex和vue-router的詳細(xì)步驟

    vue3中使用vuex和vue-router的詳細(xì)步驟

    這篇文章主要介紹了vue3中使用vuex和vue-router的步驟,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 自定義Vue組件打包、發(fā)布到npm及使用教程

    自定義Vue組件打包、發(fā)布到npm及使用教程

    這篇文章主要介紹了自定義Vue組件打包、發(fā)布到npm及使用教程 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • vue.js利用defineProperty實(shí)現(xiàn)數(shù)據(jù)的雙向綁定

    vue.js利用defineProperty實(shí)現(xiàn)數(shù)據(jù)的雙向綁定

    本篇文章主要介紹了用Node.js當(dāng)作后臺(tái)、jQuery寫前臺(tái)AJAX代碼實(shí)現(xiàn)用戶登錄和注冊(cè)的功能的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • vue post application/x-www-form-urlencoded如何實(shí)現(xiàn)傳參

    vue post application/x-www-form-urlencoded如何實(shí)現(xiàn)傳參

    這篇文章主要介紹了vue post application/x-www-form-urlencoded如何實(shí)現(xiàn)傳參問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 基于vue 實(shí)現(xiàn)表單中password輸入的顯示與隱藏功能

    基于vue 實(shí)現(xiàn)表單中password輸入的顯示與隱藏功能

    這篇文章主要介紹了vue 實(shí)現(xiàn)表單中password輸入的顯示與隱藏功能 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • vue中子組件的methods中獲取到props中的值方法

    vue中子組件的methods中獲取到props中的值方法

    今天小編就為大家分享一篇vue中子組件的methods中獲取到props中的值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • element中el-cascader級(jí)聯(lián)選擇器只有最后一級(jí)可以多選

    element中el-cascader級(jí)聯(lián)選擇器只有最后一級(jí)可以多選

    本文主要介紹了element中el-cascader級(jí)聯(lián)選擇器只有最后一級(jí)可以多選,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • Vue封裝Axios請(qǐng)求和攔截器的步驟

    Vue封裝Axios請(qǐng)求和攔截器的步驟

    這篇文章主要介紹了Vue封裝Axios請(qǐng)求和攔截器的步驟,幫助大家更好的對(duì)axios進(jìn)行封裝并將接口統(tǒng)一管理,同時(shí)為請(qǐng)求和響應(yīng)設(shè)置攔截器interceptors。,感興趣的朋友可以了解下
    2020-09-09
  • 前端使用print.js實(shí)現(xiàn)打印功能(基于vue)

    前端使用print.js實(shí)現(xiàn)打印功能(基于vue)

    最近新接了一個(gè)需求,想要在前端實(shí)現(xiàn)打印功能,下面這篇文章主要給大家介紹了關(guān)于前端使用print.js實(shí)現(xiàn)打印功能(基于vue)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Vue中的components組件與props的使用解讀

    Vue中的components組件與props的使用解讀

    這篇文章主要介紹了Vue中的components組件與props的使用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評(píng)論

丹凤县| 马尔康县| 霸州市| 游戏| 麻江县| 大庆市| 林周县| 朝阳县| 万州区| 宽甸| 东至县| 托里县| 六安市| 陇西县| 南乐县| 墨脱县| 浮山县| 陵川县| 泌阳县| 楚雄市| 博客| 集安市| 铁岭县| 阜南县| 宜黄县| 东至县| 克拉玛依市| 从化市| 辰溪县| 桂阳县| 德安县| 宁乡县| 望城县| 祁连县| 宜宾县| 南城县| 临西县| 青海省| 林甸县| 峡江县| 丰顺县|