v-for 遍歷數組
v-for 指令需要使用 item in items 形式的特殊語法,其中 items 是源數據數組,而 item 則是被迭代的數組元素的別名。
<ul id="array-with-index"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
Vue.createApp({ data() { return { parentMessage: 'Parent', items: [{ message: 'Foo' }, { message: 'Bar' }] } } }).mount('#array-with-index')
你也可以用 of 替代 in 作爲分隔符,因爲它更接近 JavaScript 迭代器的語法:
<div v-for="item of items"></div>
v-for 遍歷對象
<ul id="v-for-object" class="demo"> <li v-for="(value, name, index) in myObject"> {{ index }}. {{ name }}: {{ value }} </li> </ul>
Vue.createApp({ data() { return { myObject: { title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' } } } }).mount('#v-for-object')
在遍歷對象時,會按
Object.keys()
的結果遍歷,但是不能保證它在不同 JavaScript 引擎下的結果都一致。
維護狀態(重要)
當 Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。
如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素,並且確保它們在每個索引位置正確渲染。
這個默認的模式是高效的,但是只適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。
爲了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要爲每項提供一個唯一的 key attribute:
<div v-for="item in items" :key="item.id"> <!-- 內容 --> </div>
建議儘可能在使用 v-for 時提供 key attribute,除非遍歷輸出的 DOM 內容非常簡單,或者是刻意依賴默認行爲以獲取性能上的提升。
因爲它是 Vue 識別節點的一個通用機制,key 並不僅與 v-for 特別關聯。後面我們將在指南中看到,它還具有其它用途。
提示:不要使用對象或數組之類的非基本類型值作爲 v-for 的 key。請用字符串或數值類型的值。
Key的更多詳解:https://v3.cn.vuejs.org/api/special-attributes.html#key
數組更新檢測
1、變更數組的函數
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
使用上面的函數修改數組,就是局部修改原始數組,即:變更調用了這些方法的原始數組;
2、替換數組的函數
filter()、concat() 和 slice()
它們不會變更原始數組,而總是返回一個新數組。當使用非變更方法時,可以用新數組替換舊數組:
example1.items = example1.items.filter(item => item.message.match(/Foo/))
你可能認爲這將導致 Vue 丟棄現有 DOM 並重新渲染整個列表。其事實並非如此。Vue 爲了使得 DOM 元素得到最大範圍的重用而實現了一些智能的啓發式方法,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作。
顯示過濾/排序後的結果
有時,我們想要顯示一個數組經過過濾或排序後的版本,而不實際變更或重置原始數據。在這種情況下,可以創建一個計算屬性,來返回過濾或排序後的數組。
<li v-for="n in evenNumbers" :key="n">{{ n }}</li>
data() { return { numbers: [ 1, 2, 3, 4, 5 ] } }, computed: { evenNumbers() { return this.numbers.filter(number => number % 2 === 0) } }
在計算屬性不適用的情況下 (例如,在嵌套的 v-for 循環中) 你可以使用 方法:
<ul v-for="numbers in sets"> <li v-for="n in even(numbers)" :key="n">{{ n }}</li> </ul>
data() { return { sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]] } }, methods: { even(numbers) { return numbers.filter(number => number % 2 === 0) } }
v-for 使用整數
<div id="range" class="demo"> <span v-for="n in 10" :key="n">{{ n }} </span> </div>
在 <template> 中使用 v-for
類似於 v-if,你也可以利用帶有 v-for 的 <template> 來循環渲染一段包含多個元素的內容。
<ul> <template v-for="item in items" :key="item.msg"> <li>{{ item.msg }}</li> <li class="divider" role="presentation"></li> </template> </ul>
v-for 與 v-if 一同使用
v-if 的優先級比 v-for 更高
不推薦在一個元素上使用 v-for 和 v-if,這意味着 v-if 將沒有權限訪問 v-for 裏的變量:
<!-- 這將拋出一個錯誤,因爲“todo” property 沒有在實例上定義 --> <li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo.name }} </li>
可以把 v-for 移動到 <template> 標籤中來修正:
<template v-for="todo in todos" :key="todo.name"> <li v-if="!todo.isComplete"> {{ todo.name }} </li> </template>
在組件上使用 v-for
注意:你需要先學習 組件Component 這節,再來看這裏;
點擊查看這內容:點我
下一章:事件處理