vue的key是什麼

2022-11-29 22:01:30

在vue中,key是DOM物件的標識,是給每一個vnode的唯一id,也是diff的一種優化策略;可以根據key,更準確、 更快的找到對應的vnode節點。如果資料只做展示使用,可以使用index作為key;如果使用index作為key,而後續操作會破壞順序,一定會帶來效率問題,嚴重時會渲染出錯誤的DOM。

前端(vue)入門到精通課程,老師線上輔導:聯絡老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:windows7系統、vue3版,DELL G3電腦。

1. key是什麼

  • key在Vue是DOM物件的標識;key是給每一個vnode的唯一id,也是diff的一種優化策略,可以根據key,更準確, 更快的找到對應的vnode節點。
  • 進行列表展示時,預設key是index。
  • 如果資料只做展示使用,使用index作為key是沒有任何問題的。
  • 如果使用index作為key,而後續操作會破壞順序,一定會帶來效率問題,嚴重時會渲染出錯誤的DOM。

關於key的作用及實現原理,下面一一道來。

2. key的作用

key就是一個標識,被使用在Vue中。再詳細一點,key被使用在Vue中的虛擬DOM中,並不會出現在真實DOM中。

2.1 舉一個例子

以列表的形式展示一組人員資訊

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>key的原理</title>

    <!--引入vue-->
    <script type="text/javascript" src="../js/vue.js"></script>
    
</head>
<div id="root">
    <h2>人員列表</h2>
    <ul>
        <li v-for="(p,index) in persons">
            {{p.name}}-{{p.age}}
        </li>
    </ul>
</div>
<body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                persons:[
                    {'id':'001', 'name':'張三','age':'18'},
                    {'id':'002', 'name':'李四','age':'19'},
                    {'id':'003', 'name':'王五','age':'20'}
                ]
            }
        })
    </script>
</body>
</html>
登入後複製

這個html檔案在瀏覽器中開啟如下圖所示。

image-20211011224230413

而上述範例html檔案中並沒有使用到key,似乎也沒有問題。當然,單純地展示資料,不寫key是不會存在問題的。【學習視訊分享:、】

現在我們為上述範例加上key,這裡以每條資料的id為key

<li v-for="(p,index) in persons" :key="p.id">
    {{p.name}}-{{p.age}}
</li>
登入後複製

加上key的展示結果和上圖結果一模一樣。

image-20211011224928540

而如果我們在瀏覽器上檢視元素,不會看到key的存在。

image-20211011225246624

截至目前,我們可以得到兩個結論:1. 只做資料展示用,不寫key是沒有任何影響的;2.key不會出現在真實DOM中

實際上,即使不寫key,Vue在生成真實DOM時,也用到了key,預設是資料索引(index)

我們把key替換為index,展示的資料不會產生任何改變。

<li v-for="(p,index) in persons" :key="index">
	{{p.name}}-{{p.age}}
</li>
登入後複製

2.2 修改一下上述範例

在展示人員資訊的基礎上顯示索引,並且新增一個按鈕,功能是在頭部新增人員資訊

對上述html檔案稍加修改。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>key的原理</title>

    <!--引入vue-->
    <script type="text/javascript" src="../js/vue.js"></script>
    <link rel="icon" href="../favicon.ico" type="image/x-icon" />

</head>
<div id="root">
    <h2>人員列表</h2>
    <button @click="add">新增一個老劉</button>
    <ul>
        <li v-for="(p,index) in persons" :key="index">
            {{p.name}}-{{p.age}}-{{index}}
        </li>
    </ul>
</div>
<body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                persons:[
                    {'id':'001', 'name':'張三','age':'18'},
                    {'id':'002', 'name':'李四','age':'19'},
                    {'id':'003', 'name':'王五','age':'20'}
                ]
            },
            methods:{
                add(){
                    const p = {'id':'004', 'name':'老劉','age':'40'}
                    this.persons.unshift(p)
                }
            }
        })
    </script>
</body>
</html>
登入後複製

我們可以看到,張三、李四、王五的索引分為別0,1,2

image-20211011230442273

點選按鈕,新增一個新人物,這個時候索引發生了變化,新新增的人物「老劉」變為了索引0,似乎對,也似乎不對

image-20211011230815984

當然,單純地討論索引,這裡一點問題也沒有,下面舉一個新例子,來說說「不對「在哪裡

2.3 再修改一下範例

不展示索引了,改為輸入框,在每個人物後面的輸入框內寫上人物的姓,觀察新插入資料後原始資料的變化

稍微修改一下html

<li v-for="(p,index) in persons" :key="index">
    {{p.name}}-{{p.age}}
    <input type="text">
</li>
登入後複製

實際效果就是下圖這樣

image-20211011231349758

到這裡,似乎沒有什麼不對,接下來就是見證奇蹟的時刻

新增老劉,出現了問題,和我們預想的不一樣。

image-20211011231548484

這是key為index的情況,如果修改為資料的唯一標識,則不會產生這樣的問題。

<li v-for="(p,index) in persons" :key="p.id">
    {{p.name}}-{{p.age}}
    <input type="text">
</li>
登入後複製

誒,這就是我們想要的。

image-20211011231848647
列表內有輸入內容,後續操作破壞了原始順序,如果以index作為key,就會產生錯誤DOM

3. key的實現原理

要解釋key的實現原理,就要引入Vue一個十分重要的概念——【虛擬DOM】。

給出一組資料,Vue要把這些資料渲染到頁面上,首先要生成【虛擬DOM】,然後根據【虛擬DOM】去生成【真實的DOM】。如果資料發生了改變,Vue會生成【新的虛擬DOM】,注意,這個【新的虛擬DOM】並不會直接生成【新的真實DOM】,否則虛擬DOM一點用處也沒有了。Vue的操作是,拿根據新的資料生成的【新的虛擬DOM】與之前的【真實的DOM】去做比較,如果相同,直接延用即可(「拿來主義」);如果不同,則生成新的DOM物件。

在這個過程中key扮演了很重要的角色

根據最後一個範例進行剖析。

3.1 key為index的情況

根據資料生成【真實DOM】的流程如下:(注意,下圖的真實DOM中輸入框裡的內容為生成頁面後手動新增)

在這裡插入圖片描述

然後,新增人物「老劉」,獲取到一組新資料

在這裡插入圖片描述

Vue拿新資料生成【新的虛擬DOM】

在這裡插入圖片描述

在生成真實DOM,就需要用新生成的虛擬DOM和原來的真實DOM作比較(一條一條分析)

在這裡插入圖片描述

對比第一條,key為0,找到舊DOM中key為0的資料,發現「老劉-40」和「張三-18」不同,渲染新的資料「老劉-40」到頁面上;再往後,發現同為輸入框,不必重新渲染,直接使用原來真實DOM的內容。第一條內容就出現了,而這個輸入框還攜帶有張三的姓。

在這裡插入圖片描述

對比第二條,key為1,找到舊DOM中key為1的資料,發現「張三-18」和「李四-19」不同,渲染新的資料「張三-18」到頁面上;再往後,發現同為輸入框,不必重新渲染,直接使用原來真實DOM的內容。第二條內容就出現了,而這個輸入框還攜帶有李四的姓。

在這裡插入圖片描述

之後同理。

回顧這個過程,key是作為虛擬DOM中物件的唯一標識,標識出了資料的「身份資訊」,Vue在虛擬DOM中會根據這個「身份標識」去對比內容,設計的初衷是為了節省資源開支,不必渲染重複的部分。在本範例中,不但帶來了效率問題,還渲染出了錯誤的DOM,後果非常嚴重。

3.2 key為id的情況

直接進入新增「老劉」後的新舊DOM對比。

在這裡插入圖片描述

對比第一條,key為‘004’,發現在舊DOM中並不存在,直接生成「老劉-40」和新的輸入框。

對比第二條,key為‘001’,發現舊DOM中key為‘001’的資料相同,直接將「張三-18」和輸入框拿過來使用。

……

最後生成正確的DOM,節省了資源開支。

3.3 總結

推薦使用資料的唯一標識作為key,比如id,身份證號,手機號等等,通常這些資料由後端提供。

後續操作不破壞原來資料順序的話,使用index作為key也沒有任何問題。

更多程式設計相關知識,請存取:!!

以上就是vue的key是什麼的詳細內容,更多請關注TW511.COM其它相關文章!