vue中使用v-for時為什麼不能用index當key?以下這篇文章跟大家介紹一下 v-for 的 key 值不能是 index 的原因,希望對大家有幫助!
為什麼 v-for 的 key 值不能是 index?
很多人一說起這道老生常談的面試題,馬上就開始滔滔不絕地講述 虛擬DOM
和 diff演算法
了。
講這些沒問題,但如果是我,一定先講 v-for 的 key 值寫成 index 會造成的問題,再講原理。
曾經我寫v-for, key 值永遠都是index,直到有一天,我這麼寫造成了線上bug...
來看一下我的線上bug演示吧:
父组件代码 <Child v-for="(item, index) in list" :key="index" :count="item.count" :name="item.name" @delete="handleDelete(index)" /> list: [ { count: 1, name: '第1个元素' }, { count: 2, name: '第2个元素' }, { count: 3, name: '第3个元素' } ] handleDelete(index) { this.list.splice(index, 1) },
如程式碼和gif演示,點擊刪除第2個元素,看起來似乎一切正常。
等一下,第三個元素的count值居然變成了2,wtf! ! !
驚訝得我又去看了遍子元件的程式碼
子组件 <div> <span>{{ name }}</span> count值为:{{ innerCount }} <button @click="$emit('delete')">-</button> </div> props: { count: { type: Number, default: 0 }, name: { type: String, default: '' } }, data() { return { innerCount: this.count } }
感覺也沒什麼不對的啊。
不信邪,我又多建立了點元素來刪除,也試了下排序:
果然,不光刪除元素有問題,排序也有問題。
把 key 值改成 item.name 再試一下。
<Child v-for="(item, index) in list" :key="item.name" :count="item.count" :name="item.name" @delete="handleDelete(index)" />
正常了。
這樣看來,在 v-for 裡把 key 值寫成 index,非常危險啊。
在查閱了vue 官方文件之後,我終於明白了原因:
#當Vue 正在更新使用
v-for
渲染的元素清單時,它預設使用「就地更新」的策略。如果資料項的順序被改變,Vue 將不會移動 DOM 元素來匹配資料項的順序,而是就地更新每個元素,並確保它們在每個索引位置正確渲染。
這個預設的模式是高效率的,但是只適用於不依賴子元件狀態或暫時DOM 狀態(例如:表單輸入值) 的清單渲染輸出 。
不依賴子元件狀態
子元件裡有一行很關鍵的程式碼
data() { return { innerCount: this.count } }
子元件內部定義了innerCount,這樣子組件就有了自己的狀態,按照官方文件的說明,這種情況下不能把index 作為key 值。
臨時DOM 狀態
<div v-for="(item, index) in list1" :key="index"> <input type="text" /> <button @click="delClick(index)">删除</button> </div>
#刪除了第2項,但第3項在表單中的3變成了2 ,跟上面依賴子元件狀態的例子是一樣的。
總結
寫入清單渲染時, 依賴子元件狀態或暫時 DOM 狀態的情況,如果有 刪除、增加、排序這樣的功能,不要把 index 當作 key。
事實上,寫清單渲染時,永遠不要把 index 做成 key,key 一定要是唯一識別。
至於原因,就要理解 diff
演算法之後才能明白了。
待解答問題:
- key 為什麼不能寫成隨機數字或時間戳記?
- key 為什麼要是唯一識別?
別急,立了個寫100個 vue 問題相關文章的 flag 呢,後面的文章再慢慢分析。
希望我的 vue 系列文章能對前端路上的你有幫助~
【相關推薦:vue.js影片教學】
#以上是vue中為什麼v-for指令的 key 值不能是 index?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Vue.js是一種漸進式JavaScript框架,適用於構建複雜的用戶界面。 1)其核心概念包括響應式數據、組件化和虛擬DOM。 2)實際應用中,可以通過構建Todo應用和集成VueRouter來展示其功能。 3)調試時,建議使用VueDevtools和console.log。 4)性能優化可通過v-if/v-show、列表渲染優化和異步加載組件等實現。

Vue.js適合小型到中型項目,而React更適用於大型、複雜應用。 1.Vue.js的響應式系統通過依賴追踪自動更新DOM,易於管理數據變化。 2.React採用單向數據流,數據從父組件流向子組件,提供明確的數據流向和易於調試的結構。

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

實現 Vue 中 a 標籤跳轉的方法包括:HTML 模板中使用 a 標籤指定 href 屬性。使用 Vue 路由的 router-link 組件。使用 JavaScript 的 this.$router.push() 方法。可通過 query 參數傳遞參數,並在 router 選項中配置路由以進行動態跳轉。

Vue 中實現組件跳轉有以下方法:使用 router-link 和 <router-view> 組件進行超鏈接跳轉,指定 :to 屬性為目標路徑。直接使用 <router-view> 組件顯示當前路由渲染的組件。使用 router.push() 和 router.replace() 方法進行程序化導航,前者保存歷史記錄,後者替換當前路由不留記錄。

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

Vue.js提供了三種跳轉方式:原生 JavaScript API:使用 window.location.href 進行跳轉。 Vue Router:使用 <router-link> 標籤或 this.$router.push() 方法進行跳轉。 VueX:通過 dispatch action 或 commit mutation 來觸發路由跳轉。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1
強大的PHP整合開發環境