【vue-4】深入理解 Vue 3 中的 v-for 指令

Vue.js 作為現代前端框架的代表之一,其模板指令系統提供了強大的數據綁定和渲染能力。其中,v-for 指令是 Vue 中最常用且最重要的指令之一,它允許我們基于數據源循環渲染元素或組件。在 Vue 3 中,v-for 保留了一貫的簡潔語法,同時結合 Composition API 帶來了更靈活的使用方式。本文將全面探討 Vue 3 中 v-for 的各種用法、最佳實踐和性能優化技巧。

1. 基礎用法

1.1 數組遍歷

最基本的 v-for 用法是遍歷數組:

<template><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul>
</template><script setup>
const items = [{ id: 1, name: 'Apple' },{ id: 2, name: 'Banana' },{ id: 3, name: 'Cherry' }
]
</script>

1.2 索引值獲取

如果需要獲取當前項的索引,可以添加第二個參數:

<template><ul><li v-for="(item, index) in items" :key="item.id">{{ index }} - {{ item.name }}</li></ul>
</template>

1.3 對象遍歷

v-for 也可以遍歷對象的屬性:

<template><ul><li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li></ul>
</template><script setup>
const user = {name: 'John Doe',age: 30,occupation: 'Developer'
}
</script>

如果需要索引,還可以添加第三個參數:

<template><ul><li v-for="(value, key, index) in user" :key="key">{{ index }}. {{ key }}: {{ value }}</li></ul>
</template>

1.4 范圍遍歷

v-for 也可以接受一個整數,用于重復模板多次:

<template><span v-for="n in 5" :key="n">{{ n }}</span>
</template>

2. 關鍵概念:key 屬性

2.1 為什么需要 key

在 Vue 的虛擬 DOM 實現中,key 是一個非常重要的屬性。它為每個節點提供唯一標識,幫助 Vue 識別哪些節點發生了變化、被添加或被移除。

2.2 正確使用 key

  • 永遠不要使用索引作為 key,除非你確定列表是靜態的且不會重新排序
  • 使用唯一且穩定的 ID 作為 key
  • 如果數據沒有唯一 ID,考慮生成一個(如使用 nanoid 庫)
<!-- 不推薦 -->
<li v-for="(item, index) in items" :key="index"><!-- 推薦 -->
<li v-for="item in items" :key="item.id">

2.3 key 的作用機制

當數據變化時,Vue 會對比新舊虛擬 DOM。通過 key,Vue 可以:

  1. 高效識別哪些節點可以復用
  2. 最小化 DOM 操作
  3. 保持組件狀態(如表單輸入值)

3. 與 v-if 的結合使用

3.1 不推薦在同一元素上使用

<!-- 不推薦 -->
<li v-for="item in items" v-if="item.isActive" :key="item.id">

這種用法會導致:

  1. 渲染優先級問題(v-forv-if 有更高的優先級)
  2. 每次渲染都會遍歷整個列表,即使只有少數項需要顯示

3.2 推薦做法

  1. 使用計算屬性過濾列表
<template><li v-for="item in activeItems" :key="item.id">{{ item.name }}</li>
</template><script setup>
import { computed } from 'vue'const items = [{ id: 1, name: 'Apple', isActive: true },{ id: 2, name: 'Banana', isActive: false },{ id: 3, name: 'Cherry', isActive: true }
]const activeItems = computed(() => items.filter(item => item.isActive))
</script>
  1. 在外層元素使用 v-if
<template><ul v-if="items.length"><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul><p v-else>No items found.</p>
</template>

4. 性能優化技巧

4.1 避免大型列表渲染

對于大型列表(超過 1000 項),考慮:

  1. 分頁加載
  2. 虛擬滾動(使用 vue-virtual-scroller 等庫)
  3. 按需渲染(只渲染可視區域內的項)

4.2 使用計算屬性減少計算量

<script setup>
import { computed } from 'vue'const heavyComputedList = computed(() => {return largeArray.map(item => {// 復雜計算return transformedItem})
})
</script>

4.3 對象凍結

對于不會變化的大型列表,可以使用 Object.freeze 告訴 Vue 不需要響應式追蹤:

const largeList = Object.freeze([...])

5. 與 Composition API 結合

5.1 響應式數據源

<script setup>
import { ref, reactive } from 'vue'const array = ref([1, 2, 3])
const object = reactive({ a: 1, b: 2 })
</script>

5.2 動態操作數組

Vue 能夠檢測到以下數組方法的變化:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

對于其他操作(如直接索引賦值),需要使用特殊方法:

// 直接賦值不會觸發更新
array.value[0] = 'new value'// 應該使用
array.value.splice(0, 1, 'new value')

6. 高級用法

6.1 組件列表渲染

當渲染組件列表時,v-for 同樣適用:

<template><user-cardv-for="user in users":key="user.id":user="user"@delete="removeUser"/>
</template><script setup>
import UserCard from './UserCard.vue'const users = ref([...])
const removeUser = (id) => {users.value = users.value.filter(user => user.id !== id)
}
</script>

6.2 過渡動畫

結合 <transition-group> 為列表添加動畫:

<template><transition-group name="fade" tag="ul"><li v-for="item in items" :key="item.id">{{ item.name }}</li></transition-group>
</template><style>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
</style>

6.3 片段渲染 (Vue 3 新特性)

Vue 3 支持多根節點組件,可以更靈活地使用 v-for

<template><template v-for="item in items" :key="item.id"><h3>{{ item.title }}</h3><p>{{ item.content }}</p><hr /></template>
</template>

7. 常見問題與解決方案

7.1 列表更新不觸發渲染

問題:直接通過索引修改數組或對象屬性時,視圖不更新。

解決方案

  1. 使用 Vue 的響應式方法(如 splice
  2. 創建一個新數組/對象并替換原值
  3. 使用 Vue.set(Vue 2)或直接賦值給 ref(Vue 3)

7.2 重復的 key 警告

問題:控制臺出現 “Duplicate keys detected” 警告。

解決方案

  1. 確保每個 key 是唯一的
  2. 檢查數據源是否有重復 ID
  3. 考慮使用更復雜的 key 組合(如 ${item.id}-${index}

7.3 性能問題

問題:大型列表導致渲染緩慢。

解決方案

  1. 實現虛擬滾動
  2. 使用分頁或無限滾動
  3. 減少每個列表項的復雜度
  4. 使用 v-once 指令標記靜態內容

8. 總結

Vue 3 中的 v-for 指令是一個強大而靈活的工具,正確使用它可以高效地渲染各種數據集合。記住以下要點:

  1. 始終提供唯一的 key,避免使用索引作為 key
  2. 避免與 v-if 在同一元素上使用,優先使用計算屬性過濾數據
  3. 對于大型列表,考慮性能優化策略
  4. 結合 Composition API 可以更靈活地管理列表數據
  5. 利用 Vue 3 新特性 如多根節點支持,實現更簡潔的模板

通過掌握這些技巧,你可以構建出既高效又易于維護的列表界面,充分發揮 Vue 3 的響應式特性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90016.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90016.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90016.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《R for Data Science (2e)》免費中文翻譯 (第1章) --- Data visualization(1)

寫在前面 本系列推文為《R for Data Science (2)》的中文翻譯版本。所有內容都通過開源免費的方式上傳至Github&#xff0c;歡迎大家參與貢獻&#xff0c;詳細信息見&#xff1a; Books-zh-cn 項目介紹&#xff1a; Books-zh-cn&#xff1a;開源免費的中文書籍社區 r4ds-zh-cn …

界面組件DevExpress WPF中文教程:Grid - 如何完成節點排序和移動?

DevExpress WPF擁有120個控件和庫&#xff0c;將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有著強大互動功能的XAML基礎應用程序&#xff0c;這些應用程序專注于當代客戶的需求和構建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件…

【Prometheus+Grafana篇】監控通過Keepalived實現的MySQL HA高可用架構

&#x1f4ab;《博主主頁》&#xff1a;    &#x1f50e; CSDN主頁__奈斯DB    &#x1f50e; IF Club社區主頁__奈斯、 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對…

k8s:利用kubectl部署postgis:17-3.5

1.離線環境CPU:Hygon C86 7285 32-core Processor 操作系統&#xff1a;麒麟操作系統 containerd&#xff1a;1.7.27 Kubernetes:1.26.12 KubeSphere:4.1.2 kubekey&#xff1a;3.1.10 Harbor:2.13.1 Postgis:17-3.52.創建并執行postgresql-headless.yaml2.1創建apiVersion: v1…

Mysql(存儲過程)

目錄 介紹 特點 存儲過程創建 系統變量(不重要) 用戶變量 局部變量 if 判斷 參數&#xff08;in, out, inout) case while repeat loop 游標和條件處理程序-handler 存儲函數 為了防止以后忘記&#xff0c;反復去看視頻浪費時間&#xff0c;特寫一篇 介紹 存儲過程…

Effective Python 第14條: 用sort方法的key參數來表示復雜的排序邏輯

一、引言&#xff1a;Python排序功能的重要性 在Python開發中&#xff0c;排序功能是一個常見的需求。無論是處理數據、優化算法&#xff0c;還是提升用戶體驗&#xff0c;排序都是不可或缺的一部分。Python的列表內置了sort方法&#xff0c;提供了靈活的排序功能。然而&#…

react+antd 可拖拽模態框組件

DraggableModal 可拖拽模態框組件使用說明 概述 DraggableModal 是一個基于 dnd-kit/core 實現的可拖拽模態框組件&#xff0c;允許用戶通過拖拽標題欄來移動模態框位置。該組件具有智能邊界檢測功能&#xff0c;確保模態框始終保持在可視區域內。 功能特性 ? 可拖拽移動&…

MySQL的基本操作及相關python代碼

下面為你介紹 MySQL 的基本操作,以及對應的 Python 代碼實現。我會先介紹 SQL 基本操作,再展示如何用 Python 連接 MySQL 并執行這些操作。 一、MySQL 基本操作(SQL 語句) 1. 連接數據庫 bash mysql -u root -p2. 創建數據庫 sql CREATE DATABASE testdb;3. 使用數據…

Armbian(斐訊N1)安裝xfce桌面以及遠程環境

安裝xfce桌面以及vncserver(遠程連接) 安裝xfce桌面 apt-get install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils ubuntu的安裝gdm3&#xff0c; apt install gdm3 debian安裝lightdm。 apt install lightdm 安裝vnc server apt-get install tightvncserver 中文字體…

【Oracle】Oracle 11g打補丁時遇到opatch apply命令無法識別

?? 1. 使用完整路徑執行命令 問題原因&#xff1a;若未將$ORACLE_HOME/OPatch加入系統PATH環境變量&#xff0c;直接輸入opatch apply會因系統無法定位命令而報錯。 解決方案&#xff1a; 改用絕對路徑執行&#xff1a; $ORACLE_HOME/OPatch/opatch apply例如&#xff1a; /u…

單例模式詳細講解

一.定義單例模式是一種創建型設計模式&#xff0c;確保一個類只有一個實例&#xff0c;并提供一個全局訪問點特點&#xff1a;1.構造函數和析構函數私有化2.禁用拷貝構造函數和賦值運算符重載&#xff08;delete&#xff09;3.利用靜態成員函數和靜態成員變量來給外界提供訪問二…

KORGym:評估大語言模型推理能力的動態游戲平臺

KORGym&#xff1a;評估大語言模型推理能力的動態游戲平臺 現有評估基準多受領域限制或 pretraining 數據影響&#xff0c;難以精準測LLMs內在推理能力。KORGym平臺應運而生&#xff0c;含50余款游戲&#xff0c;多維度評估&#xff0c;本文將深入解析其設計、框架、實驗及發現…

ISPDiffuser文章翻譯理解

ISPDiffuser: Learning RAW-to-sRGB Mappings with Texture-Aware Diffusion Models and Histogram-Guided Color Consistency翻譯 Type: Conference paper Author: Yang Ren1,4, Hai Jiang1,4, Menglong Yang1,2,?, Wei Li1,2, Shuaicheng Liu3,4,? Select: ???????…

C++線程池執行步驟分析,總結線程池流程

線程池流程總結&#xff1a;1、構造函數中創建線程&#xff0c;并添加到線程池&#xff08;構造函數返回時&#xff0c;線程自動啟動&#xff0c;并停在等待wait&#xff1a;從線程池取出一個任務處&#xff09;&#xff1b; 2、主線程中添加任務&#xff0c;到任務隊列。并用“…

Java 通過 HttpURLConnection發送 http 請求

問題&#xff1a; 在調試 kill 接口的時候&#xff0c;對方的服務用的是 Django RestFramework 框架提供的接口&#xff0c;用 python 請求時得到的內容如下&#xff1a; ? ~ python3 test.py <Response [200]> "true" // 對應的代碼是 print(response, r…

【PTA數據結構 | C語言版】列出連通集

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 給定一個有 n 個頂點和 m 條邊的無向圖&#xff0c;請用深度優先遍歷&#xff08;DFS&#xff09;和廣度優先遍歷&#xff08;BFS&#xff09;分別列出其所有的連通集。假設頂點從 0 到 n?1 編號。…

GoLang教程005:switch分支

3.4 Switch分支 在 GoLand&#xff08;其實是 JetBrains 開發的 Go 編程語言 IDE&#xff09;中&#xff0c;switch 是 Go 語言&#xff08;Golang&#xff09; 的一個重要控制結構&#xff0c;用于替代多個 if-else 語句。 ? 特點說明特性說明自動 breakGo 的 switch 語句默認…

uniapp相關地圖 API調用

目錄 一、 注意事項&#xff1a; manifest.json需增加配置 二、獲取用戶收貨地址 [uni.chooseAddress] 三、獲取當前的地理位置、速度 [uni.getLocation] 四、打開地圖選擇位置、查看位置(導航) [uni.chooseLocation] [uni.openLocation] 五、使用騰訊地圖逆地址解析接口實…

Java學習----NIO模型

在 Java 的 I/O 模型中&#xff0c;NIO&#xff08;Non - Blocking I/O&#xff0c;非阻塞 I/O&#xff09;是對 BIO 的重要改進。它為高并發場景提供了更高效的處理方式&#xff0c;在眾多 Java 應用中發揮著關鍵作用。NIO模型的核心在于非阻塞和多路復用&#xff0c;其采用 “…

MySQL計數函數count原理分析

前言 統計表中數據的條數是非常常用的操作,但是咱們常用的InnoDB存儲引擎計數函數是現時統計的,所以會出現性能的問題,這次我準備分享計數函數count的原理,保證之后遇到計數方面的問題都可以輕易靈活的解決 與MyISAM存儲引擎相比,MyISAM存儲引擎是自己記錄了表中數據的條數,但…