做(zuò)自(zì)由與創造的先行(xíng)者

列表渲染

Vue.js中文手冊

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)發
下(xià)一(yī)篇:事件處理
上(shàng)一(yī)篇:條件渲染