EP8 - 列表渲染

閱讀時間約 1 分鐘
List Rendering 看這名字~難道是上一集提到的v-for ?
好像是耶!用迴圈把列表陣列裡頭的內容渲染出來~
框架把html標籤裡頭應用基本程式語法~也許應該連繼承都有?

v-for

v-for 指令用來基於陣列渲染項目列表。其語法為 item in items,其中 items 是數據來源的陣列,item 是當前迭代的元素的別名:

const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="item in items">
{{ item.message }}
</li>

v-for 的範圍內,模板表達式可以訪問所有父範圍的屬性。此外,v-for 也支持一個可選的第二個別名來表示當前項目的索引

const parentMessage = ref('Parent')
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>

Try it in the playground

v-for 的變數範圍與 JavaScript 的 forEach 方法類似:

const parentMessage = 'Parent';
const items = [
/* ... */
];

items.forEach((item, index) => {
// 可以訪問外部範圍 `parentMessage`
// 但 `item` 和 `index` 僅在這裡可用
console.log(parentMessage, item.message, index);
});

這段代碼展示了 v-for 的變數範圍如何與 forEach 回調函數的簽名相匹配。你可以像對待函數參數一樣使用解構賦值來簡化 v-for 的項目別名:

<li v-for="{ message } in items">
{{ message }}
</li>

<!-- 使用索引別名 -->
<li v-for="({ message }, index) in items">
{{ message }} {{ index }}
</li>

對於嵌套的 v-for,範圍的工作方式也類似於嵌套函數。每個 v-for 範圍都可以訪問其父範圍:

<li v-for="item in items">
<span v-for="childItem in item.children">
{{ item.message }} {{ childItem }}
</span>
</li>

你也可以使用 of 代替 in,這樣語法更接近 JavaScript 的迭代器語法:

<div v-for="item of items"></div>

v-for with an Object

你也可以使用 v-for 來遍歷物件的屬性。遍歷的順序將基於對物件調用 Object.values() 的結果:

const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
});
<ul>
<li v-for="value in myObject">
{{ value }}
</li>
</ul>

這段代碼會顯示物件 myObject 中所有屬性的值。你也可以提供第二個別名來表示屬性的名稱(也叫做 key):

<li v-for="(value, key) in myObject">
{{ key }}: {{ value }}
</li>

你還可以提供第三個別名來表示索引:

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

這樣,v-for 可以遍歷物件的屬性及其值,並且可以選擇性地顯示屬性的名稱和索引。

Try it in the playground

v-for with a Range

v-for 也可以接受一個整數。在這種情況下,它會根據範圍 1...n 重複模板多次。

<span v-for="n in 10">{{ n }}</span>

注意這裡 n 從初始值 1 開始,而不是 0。

v-for on <template>

類似於 v-if,也可在 <template> 標籤上使用 v-for 來渲染多個元素區塊。

<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>

v-for with v-if

注意: 不建議在同一個元素上同時使用 v-ifv-for,因為它們之間存在隱式的優先順序。詳細資訊請參見風格指南。(這個講第二次了www)

v-ifv-for 同時存在於同一個節點上時,v-if 的優先級高於 v-for。這意味著 v-if 條件無法訪問 v-for 的範圍內的變數:

<!--
這會拋出錯誤,因為屬性 "todo" 在實例中未定義。
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>

通過將 v-for 移到 <template> 標籤包裝起來修正這個問題(這樣也更為明確):

<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>

使用key維護狀態 - Maintaining State with key

當 Vue 更新使用 v-for 渲染的元素列表時,預設情況下,它使用 "就地補丁"(in-place patch) 策略。如果資料項目的順序發生了變化,Vue 會在原地補丁每個元素,確保它反映當前應該渲染的內容,而不是移動 DOM 元素以匹配項目的順序。

這種預設模式效率很高,但僅適用於列表渲染輸出不依賴於子組件狀態或臨時 DOM 狀態(例如表單輸入值)的情況。

為了讓 Vue 能夠跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每個項目提供一個唯一的 key 屬性:

<div v-for="item in items" :key="item.id">
<!-- 內容 -->
</div>

當使用 <template v-for> 時,key 應該放在 <template> 容器上:

<template v-for="todo in todos" :key="todo.name">
<li>{{ todo.name }}</li>
</template>

注意: 這裡的 key 是一個特殊的屬性,用於綁定 v-bind。它不應與在使用 v-for 遍歷物件時的屬性 key 變數混淆。

建議在使用 v-for 時提供 key 屬性,除非迭代的 DOM 內容很簡單(即不包含組件或有狀態的 DOM 元素),或你有意依賴預設行為以獲得性能提升。

key 綁定應該使用基本值,如字符串和數字。不要使用物件作為 v-forkey。有關 key 屬性的詳細使用,請參見 key API 文檔

v-for with a Component

本節假設你對組件已有了解。如果不熟悉,建議稍後再回來閱讀。

你可以像使用普通元素一樣,直接在組件上使用 v-for(別忘了提供 key):

<MyComponent v-for="item in items" :key="item.id" />

然而,這樣做不會自動將任何數據傳遞給組件,因為組件具有獨立的作用域。為了將迭代數據傳遞給組件,我們還需要使用 props

<MyComponent
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
/>

不自動將 item 注入組件的原因是,這樣會使組件與 v-for 的實現方式緊密耦合。明確數據來源使得組件可以在其他情況下重用。

查看這個簡單的待辦事項列表範例,了解如何使用 v-for 渲染一組組件並向每個實例傳遞不同的數據。

陣列變化檢測 - Array Change Detection

變異方法 - Mutation Methods

Vue 能夠檢測到當一個響應式陣列的變異方法被調用時,並觸發必要的更新。這些變異方法包括:

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

替換陣列 - Replacing an Array

變異方法會修改它們所調用的原始陣列。相比之下,還有一些非變異方法,如 filter()concat()slice(),這些方法不會修改原始陣列,而是返回一個新陣列。當使用這些非變異方法時,我們應該用新陣列替換舊陣列:

// `items` 是一個具有陣列值的 ref
items.value = items.value.filter((item) => item.message.match(/Foo/))

你可能會擔心這會導致 Vue 丟棄現有的 DOM 並重新渲染整個列表,但實際上並非如此。Vue 實施了智能的啟發式算法以最大化 DOM 元素的重用,因此用另一個包含重疊對象的陣列替換陣列是一個非常高效的操作。

顯示過濾或排序後的結果 - Displaying Filtered/Sorted Results

有時我們希望顯示過濾或排序後的陣列版本,而不實際修改或重置原始數據。在這種情況下,可以創建一個計算屬性來返回過濾或排序後的陣列。

const numbers = ref([1, 2, 3, 4, 5])

const evenNumbers = computed(() => {
return numbers.value.filter((n) => n % 2 === 0)
})

在這裡,我們有一個 numbers 陣列,並使用 computed 來創建一個新的計算屬性 evenNumbers。這個計算屬性會返回所有偶數。模板可以這樣顯示:

<li v-for="n in evenNumbers">{{ n }}</li>

如果計算屬性不適用(例如在多層嵌套的 v-for 中),可使用方法來過濾或排序數據。

const sets = ref([
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
])

function even(numbers) {
return numbers.filter((number) => number % 2 === 0)
}

在這裡,我們有一個 sets 陣列,包含多個數字陣列。我們定義了一個方法 even,用來過濾出偶數。在模板中,可以這樣使用:

<ul v-for="numbers in sets">
<li v-for="n in even(numbers)">{{ n }}</li>
</ul>

使用 reverse()sort() 方法時要小心,因為這些方法會修改原始陣列。為了避免計算屬性中直接修改原始數據,應先創建原始數組的副本,再進行排序或反轉操作。

// 不建議的做法
// return numbers.reverse()

// 推薦的做法 創建原始數組的副本,再進行操作
return [...numbers].reverse()

補充:[...numbers]

...numbers:這是展開運算符(spread operator),用來將 numbers 陣列中的所有元素展開成單獨的元素。例如,如果 numbers[1, 2, 3],那麼 ...numbers 就相當於 1, 2, 3

[...numbers]:這裡用展開運算符將 numbers 陣列中的元素展開,然後包裹在新的陣列中,從而創建一個新的副本,而不改變原始的 numbers 陣列。這意味著你現在有了一個與 numbers 內容相同但獨立於它的新的陣列。

持續學習各種框架特性!
但會有一些例外~什麼東西不能跟什麼東西一起用~
原因是什麼理由是什麼~還需要好好內化吸收一下www
一起來吸收~~~






avatar-img
2會員
70內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
Conditional Rendering 根據條件決定是否渲染元素。Vue.js 的 v-if 在條件為真時渲染,v-else-if 處理額外條件,v-show 始終渲染元素但用 CSS 控制顯示。v-if 會創建或銷毀元素,v-show 只改變顯示樣式。
這篇文章介紹了在 Vue.js 前端框架中如何有效地綁定 Class 和 Style。透過使用 v-bind 指令,使用者可以動態地切換元素的類別和內聯樣式,這不僅能夠簡化程式碼,還能防止錯誤的發生。文章中探討了物件和陣列綁定的使用情境,以及如何在組件中應用這些技術,從而提升開發效率與程式的可讀性。
本文介紹了計算屬性(Computed Properties)的基本概念及其在前端框架中的應用,特別是 Vue.js。計算屬性允許我們根據其他響應式數據進行計算並且自動跟蹤依賴,避免不必要的重複計算。本文還探討瞭如何使用可寫入的計算屬性,以及最佳實踐建議,以確保性能與代碼的可讀性。
本文深入探討 Vue.js 中的響應式原理,特別是 Composition API 中的 ref() 和 reactive() 使用。通過示例分析這些概念,並比較二者的優缺點,幫助開發者更清晰地理解響應式狀態的管理與最佳實踐。瞭解如何有效地聲明和管理響應式狀態,對於提升 Vue 開發的效率至關重要。
本文介紹了 Vue 的模板語法及虛擬 DOM 概念。學習如何使用 Vue 進行聲明式渲染,以及模板如何轉換為高效的 JavaScript 代碼。探討各種綁定方法、指令及安全注意事項,幫助開發者構建高效動態用戶界面並提升應用性能。文章深入淺出,適合想進一步瞭解 Vue 的開發者。
這篇文章將介紹如何創建和管理 Vue 應用程式的基本概念,包括根組件的概念、如何掛載應用程式及應用程式的配置選項。將探討多個應用實例的使用情境,並解釋如何在同一頁面上共存不同的 Vue 應用程式。透過範例和深入的說明,讀者將能夠理解 Vue 應用程式的組織結構和應用範圍內的資產管理。
Conditional Rendering 根據條件決定是否渲染元素。Vue.js 的 v-if 在條件為真時渲染,v-else-if 處理額外條件,v-show 始終渲染元素但用 CSS 控制顯示。v-if 會創建或銷毀元素,v-show 只改變顯示樣式。
這篇文章介紹了在 Vue.js 前端框架中如何有效地綁定 Class 和 Style。透過使用 v-bind 指令,使用者可以動態地切換元素的類別和內聯樣式,這不僅能夠簡化程式碼,還能防止錯誤的發生。文章中探討了物件和陣列綁定的使用情境,以及如何在組件中應用這些技術,從而提升開發效率與程式的可讀性。
本文介紹了計算屬性(Computed Properties)的基本概念及其在前端框架中的應用,特別是 Vue.js。計算屬性允許我們根據其他響應式數據進行計算並且自動跟蹤依賴,避免不必要的重複計算。本文還探討瞭如何使用可寫入的計算屬性,以及最佳實踐建議,以確保性能與代碼的可讀性。
本文深入探討 Vue.js 中的響應式原理,特別是 Composition API 中的 ref() 和 reactive() 使用。通過示例分析這些概念,並比較二者的優缺點,幫助開發者更清晰地理解響應式狀態的管理與最佳實踐。瞭解如何有效地聲明和管理響應式狀態,對於提升 Vue 開發的效率至關重要。
本文介紹了 Vue 的模板語法及虛擬 DOM 概念。學習如何使用 Vue 進行聲明式渲染,以及模板如何轉換為高效的 JavaScript 代碼。探討各種綁定方法、指令及安全注意事項,幫助開發者構建高效動態用戶界面並提升應用性能。文章深入淺出,適合想進一步瞭解 Vue 的開發者。
這篇文章將介紹如何創建和管理 Vue 應用程式的基本概念,包括根組件的概念、如何掛載應用程式及應用程式的配置選項。將探討多個應用實例的使用情境,並解釋如何在同一頁面上共存不同的 Vue 應用程式。透過範例和深入的說明,讀者將能夠理解 Vue 應用程式的組織結構和應用範圍內的資產管理。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
我們在實作中,難免會遇到在不同組件中,卻有需求相同的資料格式,因此 mixins 可以達到我們的需求,除了 data 以外也包含了 methods 可以共用,舉例來說,學生資料可能會在,班級跟社團內被使用,當我們要撰寫元件時,就可以省略多餘的 data 定義。