v-for
我們可以使用(yòng) v-for 指令基于一個數組來(lái)渲染一個列表。v-for 指令的值需要使用(yòng) item in items 形式的特殊語法,其中 items 是源數據的數組,而 item 是叠代項的别名:
js
data() {
return {
items: [{ message: 'Foo' }, { message: 'Bar' }]
}
}
template
<li v-for="item in items">
{{ item.message }}
</li>
在 v-for 塊中可以完整地訪問父作(zuò)用(yòng)域内的屬性和(hé)變量。v-for 也(yě)支持使用(yòng)可選的第二個參數表示當前項的位置索引。
js
data() {
return {
parentMessage: 'Parent',
items: [{ message: 'Foo' }, { message: 'Bar' }]
}
}
template
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
Parent - 0 - Foo
Parent - 1 - Bar
v-for 變量的作(zuò)用(yòng)域和(hé)下(xià)面的 JavaScript 代碼很(hěn)類似:
js
const parentMessage = 'Parent'
const items = [
/* ... */
]
items.forEach((item, index) => {
// 可以訪問外(wài)層的 `parentMessage`
// 而 `item` 和(hé) `index` 隻在這(zhè)個作(zuò)用(yòng)域可用(yòng)
console.log(parentMessage, item.message, index)
})
注意 v-for 是如何對(duì)應 forEach 回調的函數簽名的。實際上(shàng),你(nǐ)也(yě)可以在定義 v-for 的變量别名時(shí)使用(yòng)解構,和(hé)解構函數參數類似:
template
<li v-for="{ message } in items">
{{ message }}
</li>
<!-- 有 index 索引時(shí) -->
<li v-for="({ message }, index) in items">
{{ message }} {{ index }}
</li>
對(duì)于多層嵌套的 v-for,作(zuò)用(yòng)域的工(gōng)作(zuò)方式和(hé)函數的作(zuò)用(yòng)域很(hěn)類似。每個 v-for 作(zuò)用(yòng)域都可以訪問到(dào)父級作(zuò)用(yòng)域:
template
<li v-for="item in items">
<span v-for="childItem in item.children">
{{ item.message }} {{ childItem }}
</span>
</li>
你(nǐ)也(yě)可以使用(yòng) of 作(zuò)爲分隔符來(lái)替代 in,這(zhè)更接近 JavaScript 的叠代器語法:
template
<div v-for="item of items"></div>
v-for 與對(duì)象
你(nǐ)也(yě)可以使用(yòng) v-for 來(lái)遍曆一個對(duì)象的所有屬性。遍曆的順序會(huì)基于對(duì)該對(duì)象調用(yòng) Object.keys() 的返回值來(lái)決定。
js
data() {
return {
myObject: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
}
template
<ul>
<li v-for="value in myObject">
{{ value }}
</li>
</ul>
可以通過提供第二個參數表示屬性名 (例如 key):
template
<li v-for="(value, key) in myObject">
{{ key }}: {{ value }}
</li>
第三個參數表示位置索引:
template
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
在 v-for 裏使用(yòng)範圍值
v-for 可以直接接受一個整數值。在這(zhè)種用(yòng)例中,會(huì)将該模闆基于 1...n 的取值範圍重複多次。
template
<span v-for="n in 10">{{ n }}</span>
注意此處 n 的初值是從(cóng) 1 開(kāi)始而非 0。
<template> 上(shàng)的 v-for
與模闆上(shàng)的 v-if 類似,你(nǐ)也(yě)可以在 <template> 标簽上(shàng)使用(yòng) v-for 來(lái)渲染一個包含多個元素的塊。例如:
template
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for 與 v-if
當它們同時(shí)存在于一個節點上(shàng)時(shí),v-if 比 v-for 的優先級更高(gāo)。這(zhè)意味着 v-if 的條件将無法訪問到(dào) v-for 作(zuò)用(yòng)域内定義的變量别名:
template
<!--
這(zhè)會(huì)抛出一個錯誤,因爲屬性 todo 此時(shí)
沒有在該實例上(shàng)定義
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
在外(wài)新包裝一層 <template> 再在其上(shàng)使用(yòng) v-for 可以解決這(zhè)個問題 (這(zhè)也(yě)更加明(míng)顯易讀):
template
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
通過 key 管理(lǐ)狀态
Vue 默認按照“就地更新”的策略來(lái)更新通過 v-for 渲染的元素列表。當數據項的順序改變時(shí),Vue 不會(huì)随之移動 DOM 元素的順序,而是就地更新每個元素,确保它們在原本指定的索引位置上(shàng)渲染。
默認模式是高(gāo)效的,但(dàn)隻适用(yòng)于列表渲染輸出的結果不依賴子組件狀态或者臨時(shí) DOM 狀态 (例如表單輸入值) 的情況。
爲了(le)給 Vue 一個提示,以便它可以跟蹤每個節點的标識,從(cóng)而重用(yòng)和(hé)重新排序現(xiàn)有的元素,你(nǐ)需要爲每個元素對(duì)應的塊提供一個唯一的 key attribute:
template
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
當你(nǐ)使用(yòng) <template v-for> 時(shí),key 應該被放(fàng)置在這(zhè)個 <template> 容器上(shàng):
<template v-for="todo in todos" :key="todo.name">
<li>{{ todo.name }}</li>
</template>
注意
key 在這(zhè)裏是一個通過 v-bind 綁定的特殊 attribute。請(qǐng)不要和(hé)在 v-for 中使用(yòng)對(duì)象裏所提到(dào)的對(duì)象屬性名相混淆。
推薦在任何可行的時(shí)候爲 v-for 提供一個 key attribute,除非所叠代的 DOM 内容非常簡單 (例如:不包含組件或有狀态的 DOM 元素),或者你(nǐ)想有意采用(yòng)默認行爲來(lái)提高(gāo)性能(néng)。
key 綁定的值期望是一個基礎類型的值,例如字符串或 number 類型。不要用(yòng)對(duì)象作(zuò)爲 v-for 的 key。關于 key attribute 的更多用(yòng)途細節,請(qǐng)參閱 key API 文(wén)檔。
組件上(shàng)使用(yòng) v-for
這(zhè)一小(xiǎo)節假設你(nǐ)已了(le)解組件的相關知(zhī)識,或者你(nǐ)也(yě)可以先跳過這(zhè)裏,之後再回來(lái)看(kàn)。
我們可以直接在組件上(shàng)使用(yòng) v-for,和(hé)在一般的元素上(shàng)使用(yòng)沒有區(qū)别 (别忘記提供一個 key):
template
<MyComponent v-for="item in items" :key="item.id" />
但(dàn)是,這(zhè)不會(huì)自(zì)動将任何數據傳遞給組件,因爲組件有自(zì)己獨立的作(zuò)用(yòng)域。爲了(le)将叠代後的數據傳遞到(dào)組件中,我們還需要傳遞 props:
template
<MyComponent
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
/>
不自(zì)動将 item 注入組件的原因是,這(zhè)會(huì)使組件與 v-for 的工(gōng)作(zuò)方式緊密耦合。明(míng)确其數據的來(lái)源可以使組件在其他(tā)情況下(xià)重用(yòng)。
網站(zhàn)建設開(kāi)發|APP設計(jì)開(kāi)發|小(xiǎo)程序建設開(kāi)發