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