Rendu de liste
Répertoire
Utilisez v-for
pour faire correspondre un tableau à un ensemble d'élémentsv-for
把一个数组对应为一组元素
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul> var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
结果:
在 v-for
块中,我们可以访问所有父作用域的属性。v-for
还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
结果:
你也可以用 of
替代 in
作为分隔符,因为它更接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
在 v-for
里使用对象
你也可以用 v-for
Nous peut utiliser la directive
v-for
pour afficher une liste basée sur un tableau. La directive v-for
nécessite une syntaxe spéciale de la forme item in items
, où items
est le tableau de données source et item code > est le alias
de l'élément du tableau en cours d'itération. <ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
Résultats : 
Dans le bloc v-for
, nous pouvons accéder à toutes les propriétés de la portée parent. v-for
prend également en charge un deuxième argument facultatif, l'index de l'élément actuel. 
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
Résultats : 🎜🎜
🎜🎜Vous pouvez également utiliser of
au lieu de in
comme délimiteur car il est plus proche de la syntaxe des itérateurs JavaScript : 🎜<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
🎜🎜🎜🎜🎜Utilisez des objets dans v-for
🎜
🎜Vous pouvez également utiliser v-for
pour parcourir Une propriété d'un objet. 🎜<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
🎜Résultat : 🎜🎜🎜🎜🎜Vous pouvez également fournir le deuxième paramètre comme nom de propriété (c'est-à-dire le nom de la clé) : 🎜var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
🎜🎜🎜Vous pouvez également utiliser le troisième paramètre comme index :
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

Lors du parcours de l'objet, il sera parcouru en fonction du résultat de Object.keys()
, mais Object.keys()
的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。
维护状态
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"
。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
属性:
vm.$set(vm.items, indexOfItem, newValue)
建议尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key
并不仅与 v-for
特别关联。后面我们将在指南中看到,它还具有其它用途。
不要使用对象或数组之类的非基本类型值作为 v-for
的 key
。请用字符串或数值类型的值。
更多 key
attribute 的细节用法请移步至 key
的 API 文档。
数组更新检测
变异方法 (mutation method)
Vue 将被侦听的数组的变异方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你可以打开控制台,然后对前面例子的 items
数组尝试调用变异方法。比如 example1.items.push({ message: 'Baz' })
ne peut pas
garantir que son résultat est cohérent sous différents moteurs JavaScript.
État de maintenance
À utiliser lorsque Vue est en cours mis à jour Lorsque v-for
rend une liste d'éléments, il utilise la stratégie "mise à jour sur place" par défaut. Si l'ordre des éléments de données est modifié, Vue ne déplacera pas les éléments DOM pour qu'ils correspondent à l'ordre des éléments de données, mais mettra à jour chaque élément en place et garantira qu'ils s'affichent correctement à chaque position d'index. Ceci est similaire au track-by="$index"
de Vue 1.x. 🎜Ce mode par défaut est efficace, mais 🎜s'applique uniquement à la sortie de rendu de liste🎜 qui ne repose pas sur l'état du sous-composant ou sur l'état temporaire du DOM (par exemple, les valeurs d'entrée du formulaire). 🎜🎜Pour donner un indice à Vue afin qu'il puisse garder une trace de l'identité de chaque nœud et ainsi réutiliser et réorganiser les éléments existants, vous devez fournir un attribut key
unique pour chaque élément : 🎜vm.items.splice(newLength)
🎜Recommandé Il est possible de fournir l'attribut key
lors de l'utilisation de v-for
à moins que la traversée du contenu DOM de sortie soit très simple, ou que le comportement par défaut soit délibérément utilisé pour gagner en performances. 🎜🎜Parce qu'il s'agit d'un mécanisme général permettant à Vue d'identifier les nœuds, key
n'est pas spécifiquement lié uniquement à v-for
. Comme nous le verrons plus loin dans le guide, il a également d’autres utilisations. 🎜🎜🎜N'utilisez pas de valeurs de type non basiques telles que des objets ou des tableaux comme key
de v-for
. Veuillez utiliser une chaîne ou une valeur numérique. 🎜🎜Pour une utilisation plus détaillée de l'attribut key
, veuillez vous rendre sur Documentation API pour clé
. 🎜🎜🎜🎜🎜Détection de mise à jour du tableau🎜🎜
🎜🎜🎜🎜🎜mutation method🎜🎜🎜🎜Vue encapsule les méthodes de mutation du tableau écouté, elles déclencheront donc également des mises à jour de vue. Ces méthodes encapsulées incluent : 🎜
- 🎜
push()
🎜 - 🎜
pop()
🎜 - 🎜
shift()
🎜 - 🎜
unshift()
🎜 - 🎜
splice()
🎜 - 🎜
sort()
🎜 - 🎜
reverse() code>🎜
🎜Vous pouvez ouvrir la console et essayer d'appeler la méthode de mutation sur le tableau items
dans l'exemple précédent. Par exemple, example1.items.push({ message : 'Baz' })
. 🎜🎜🎜🎜🎜🎜🎜Remplacer le tableau🎜🎜🎜Les méthodes de mutation, comme leur nom l'indique, changeront le tableau d'origine sur lequel ces méthodes sont appelées. En revanche, il existe également des méthodes non mutantes, telles que filter()
, concat()
et slice()
. Ils ne modifient pas le tableau d'origine, mais renvoient toujours un nouveau tableau. Lorsque vous utilisez l'approche sans mutation, vous pouvez remplacer l'ancien tableau par le nouveau : filter()
、concat()
和 slice()
。它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
注意事项
由于 JavaScript 的限制,Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
举个例子:
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将在响应式系统内触发状态更新:
Vue.set(vm.userProfile, 'age', 27)
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.userProfile, 'age', 27)
为了解决第二类问题,你可以使用 splice
:
Object.assign(vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
对象变更检测注意事项
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value)
方法向嵌套对象添加响应式属性。例如,对于:
<li v-for="n in evenNumbers">{{ n }}</li>
你可以添加一个新的 age
属性到嵌套的 userProfile
对象:
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
你还可以使用 vm.$set
实例方法,它只是全局 Vue.set
的别名:
<li v-for="n in even(numbers)">{{ n }}</li>
有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign()
或 _.extend()
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
Vous pourriez penser que cela amènerait Vue à supprimer le DOM existant et à restituer la liste entière. Heureusement, ce n'est pas le cas. Vue implémente des heuristiques intelligentes afin de maximiser la réutilisation des éléments DOM, donc remplacer le tableau d'origine par un tableau contenant les mêmes éléments est une opération très efficace.
Notes
🎜En raison des limitations de JavaScript, Vue < strong>Impossible de détecter les changements dans les tableaux suivants : 🎜- 🎜Lorsque vous définissez un élément de tableau directement à l'aide d'un index, par exemple :
vm.items[indexOfItem] = newValue
🎜 - 🎜Lorsque vous modifiez la longueur du tableau, par exemple :
vm.items.length = newLength
🎜< /li>
🎜Par exemple : 🎜<div>
<span v-for="n in 10">{{ n }} </span>
</div>
🎜Afin de résoudre le premier type de problème, les deux méthodes suivantes peuvent obtenir le même effet que vm.items[indexOfItem] = newValue
, et sera également utilisé dans les mises à jour du statut des déclencheurs au sein d'un système réactif : 🎜<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
🎜Vous pouvez également utiliser vm. $set
méthode d'instance, qui est un alias de la méthode globale Vue.set
: 🎜<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
🎜Afin de résoudre le deuxième type de problème , vous pouvez utiliser splice< /code>:🎜<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
🎜🎜🎜Considérations sur la détection des changements d'objet strong> h2>
🎜Ou en raison des limitations de JavaScript, Vue ne peut pas détecter l'ajout ou la suppression de propriétés d'objet : 🎜<my-component v-for="item in items" :key="item.id"></my-component>
🎜Pour les instances déjà créées, Vue ne le fait pas permettre l'ajout dynamique de propriétés réactives au niveau racine. Cependant, vous pouvez ajouter des propriétés réactives aux objets imbriqués à l'aide de la méthode Vue.set(object, propertyName, value)
. Par exemple, pour : 🎜<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
></my-component>
🎜 Vous pouvez ajouter une nouvelle propriété age
à l'objet userProfile
imbriqué : 🎜<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat"
>
<button>Add</button>
</form>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"
></li>
</ul>
</div>
🎜Vous pouvez également utiliser vm.$set < /code> Méthode d'instance, il s'agit simplement d'un alias du Vue.set
global : 🎜Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})
🎜Parfois, vous devrez peut-être attribuer plusieurs nouvelles propriétés à un objet existant, par exemple en utilisant Object. assign()
ou _.extend()
. Dans ce cas, vous devez créer un nouvel objet avec les propriétés des deux objets. Donc, si vous souhaitez ajouter un nouvel attribut responsive, au lieu de ceci : 🎜rrreee🎜 vous devriez faire ceci : 🎜rrreee🎜🎜🎜Afficher les résultats filtrés/triés
Parfois, nous souhaitons afficher une version filtrée ou triée d'un tableau sans réellement modifier ou réinitialiser les données d'origine. Dans ce cas, vous pouvez créer une propriété calculée qui renvoie un tableau filtré ou trié.
Par exemple :
rrreeerrreeeDans les cas où les propriétés calculées ne sont pas applicables (par exemple, dans des boucles v-for
imbriquées), vous pouvez utiliser une méthode : v-for
循环中) 你可以使用一个方法:
rrreeerrreee
在 v-for
里使用值范围
v-for
也可以接受整数。在这种情况下,它会把模板重复对应次数。
rrreee结果:

在 <template>
上使用 v-for
类似于 v-if
,你也可以利用带有 v-for
的 <template>
来循环渲染一段包含多个元素的内容。比如:
rrreee
v-for 与 v-if 一同使用
注意我们不推荐在同一元素上使用 v-if
和 v-for
。更多细节可查阅 风格指南。
当它们处于同一节点,v-for
的优先级比 v-if
更高,这意味着 v-if
将分别重复运行于每个 v-for
循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:
rrreee上面的代码将只渲染未完成的 todo。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if
置于外层元素 (或 <template>
)上。如:
rrreee
在组件上使用 v-for
这部分内容假定你已经了解组件相关知识。你也完全可以先跳过它,以后再回来查看。
在自定义组件上,你可以像在任何普通元素上一样使用 v-for
。
rrreee2.2.0+ 的版本里,当在组件上使用 v-for
时,key
rrreeerrreee
🎜🎜Utiliser des plages de valeurs dans v-for
🎜🎜🎜🎜🎜v-for
peut également accepter des nombres entiers. Dans ce cas, il répétera le modèle le nombre de fois correspondant. 🎜rrreee🎜Résultats : 🎜🎜
🎜🎜
🎜🎜🎜Utilisez v-for
sur <template>
🎜🎜🎜🎜🎜Similaire à < code>v-if
, vous pouvez également utiliser <template>
avec v-for
pour restituer un contenu contenant plusieurs éléments dans une boucle. Par exemple : 🎜rrreee🎜
🎜🎜🎜v-for est utilisé avec v-if🎜🎜🎜🎜🎜Notez que nous 🎜 ne le faisons pas 🎜 Je recommande d'utiliser le même élément. Utilisez v-if
et v-for
. Plus de détails peuvent être trouvésstyle Guide. 🎜
🎜Lorsqu'ils sont sur le même nœud, v-for
a une priorité plus élevée que v-if
, ce qui signifie v-if code> code> sera exécuté individuellement et à plusieurs reprises dans chaque boucle v-for
. Ce mécanisme de priorité est utile lorsque vous souhaitez uniquement afficher les nœuds pour certains éléments, comme suit : 🎜rrreee🎜Le code ci-dessus ne rendra que les tâches inachevées. 🎜🎜Et si votre objectif est d'ignorer conditionnellement l'exécution de la boucle, alors vous pouvez placer v-if
dans l'élément externe (ou <template>
). Tels que : 🎜rrreee🎜
🎜🎜🎜Utilisez v-for
sur le composant🎜🎜🎜🎜🎜🎜Cette partie suppose que vous avez déjà comprendre 🎜🎜Components🎜🎜Connaissances connexes. Vous pouvez également l'ignorer et y revenir plus tard. 🎜🎜
🎜Sur les composants personnalisés, vous pouvez utiliser v-for
comme vous le feriez sur n'importe quel élément normal. 🎜rrreee🎜🎜Dans la version 2.2.0+, lors de l'utilisation de v-for
sur un composant, key
est désormais requis. 🎜🎜
Cependant, aucune donnée ne sera automatiquement transmise au composant car le composant a sa propre portée indépendante. Afin de transmettre les données d'itération au composant, nous devons utiliser prop :
rrreeeLa raison pour laquelle item
n'est pas automatiquement injecté dans le composant est que cela rendra le composant différent de Les opérations de v-for
sont étroitement couplées. Clarifier la source des données d'un composant permet de réutiliser le composant dans d'autres situations. item
注入到组件里的原因是,这会使得组件与 v-for
的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。
下面是一个简单的 todo 列表的完整例子:
rrreee注意这里的 is="todo-item"
属性。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul>
元素内只有 <li>
元素会被看作有效内容。这样做实现的效果与 <todo-item>
Voici un exemple complet d'une simple liste de tâches : rrreee
Notez l'attribut is="todo-item"
ici. Cette approche est très nécessaire lors de l'utilisation de modèles DOM, car seul l'élément <li>
au sein de l'élément <ul>
sera considéré comme un contenu valide. Cela produit le même effet que <todo-item>
, mais peut éviter certaines erreurs potentielles d'analyse du navigateur. Consultez les
Instructions d'analyse du modèle DOM pour en savoir plus. 
rrreee
🎜🎜 🎜