做自(zì)由與創造的先行者

列表渲染

Vue.js中文(wén)手冊

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