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
留言分享你的想法!
avatar-img
卡關的人生
2會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
VUE為單向資料流的框架,在鄰近層級之間我們可以依靠 props 由父層向子層來傳遞需要的資料,然而遇到跨層級的架構時,雖然也是可以一層層傳進去,只是這會造成多餘的處理及凌亂的程式碼,因此才有了 "provide" 來解決我們跨層級的需求。 層級展示圖
Thumbnail
VUE為單向資料流的框架,在鄰近層級之間我們可以依靠 props 由父層向子層來傳遞需要的資料,然而遇到跨層級的架構時,雖然也是可以一層層傳進去,只是這會造成多餘的處理及凌亂的程式碼,因此才有了 "provide" 來解決我們跨層級的需求。 層級展示圖
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
2023 Vue直播班筆記 - 動態路由Props,接續之前的一般動態路由。分為 "寫死" 及 "彈性" 兩種。
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
Thumbnail
這系列是我在 2023 六角學院 Vue作品實戰班的筆記,筆記以本人理解的方式記錄。此篇主題為 Slot Props 進階應用 ,其中包含單筆資料、多筆資料。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News