Listenwiedergabe
Verzeichnis
Verwenden Sie v-for, um ein Array einer Menge von Elementen zuzuordnen
auf <template> ; v-for und v-if Verwenden Sie
Verwendenv-for
Wenn wir ein Array einer Menge von Elementen
entsprechen, können wir die Direktive v-for
verwenden, um eine Liste basierend auf einem Array zu rendern. Die v-for
-Direktive erfordert eine spezielle Syntax der Form item in items
, wobei items
das Quelldatenarray und item
der Alias des zu iterierenden Array-Elements ist.
<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' } ] } })
Ergebnis:
Im v-for
-Block können wir auf alle Eigenschaften des übergeordneten Bereichs zugreifen. v-for
unterstützt auch einen optionalen zweiten Parameter, der den Index des aktuellen Elements darstellt.
<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' } ] } })
Ergebnis:
Sie können auch of
anstelle von in
als Trennzeichen verwenden, da es näher an JavaScript ist Die Syntax des Iterators:
<div v-for="item of items"></div>
Use object in v-for
you You kann auch v-for
verwenden, um die Eigenschaften eines Objekts zu durchlaufen.
<ul id="v-for-object" class="demo"> <li v-for="value in object"> {{ value }} </li> </ul>
new Vue({ el: '#v-for-object', data: { object: { title: 'How to do lists in Vue', author: 'Jane Doe', publishedAt: '2016-04-10' } } })
Ergebnis:
Sie können den zweiten Parameter auch als Eigenschaftsnamen (d. h. Schlüsselnamen) angeben:
<div v-for="(value, name) in object"> {{ name }}: {{ value }} </div>
Sie können den dritten Parameter auch als Index verwenden:
<div v-for="(value, name, index) in object"> {{ index }}. {{ name }}: {{ value }} </div>
Beim Durchlaufen des Objekts wird das Ergebnis von
Object.keys()
durchlaufen, aber Es gibt keine Garantie dafür, dass die Ergebnisse unter verschiedenen JavaScript-Engines konsistent sind.
Wartungsstatus
Wenn Vue aktualisiert wird, verwenden Sie v-for
, um render Es verwendet standardmäßig die Strategie der „In-Place-Aktualisierung“, wenn es um eine Liste von Elementen geht. Wenn die Reihenfolge der Datenelemente geändert wird, verschiebt Vue die DOM-Elemente nicht, um sie an die Reihenfolge der Datenelemente anzupassen, sondern aktualisiert jedes Element an seiner Stelle und stellt sicher, dass sie an jeder Indexposition korrekt gerendert werden. Dies ähnelt dem track-by="$index"
von Vue 1.x.
Dieser Standardmodus ist effizient, aber eignet sich nur für die Listenwiedergabeausgabe , die nicht auf dem Status der untergeordneten Komponente oder dem temporären DOM-Status basiert (z. B. Formulareingabewerte).
Um Vue einen Hinweis zu geben, damit es die Identität jedes Knotens verfolgen und somit vorhandene Elemente wiederverwenden und neu anordnen kann, müssen Sie für jedes Element ein eindeutiges key
-Attribut bereitstellen:
<div v-for="item in items" v-bind:key="item.id"> <!-- 内容 --> </div>
Es wird empfohlen, bei Verwendung von v-for
nach Möglichkeit das Attribut key
bereitzustellen, es sei denn, das Durchlaufen des Ausgabe-DOM-Inhalts ist sehr einfach oder Sie verlassen sich bewusst auf das Standardverhalten, um Leistungsverbesserungen zu erzielen.
Da es sich um einen allgemeinen Mechanismus für Vue zur Identifizierung von Knoten handelt, bezieht sich key
nicht speziell nur auf v-for
. Wie wir später in der Anleitung sehen werden, hat es auch andere Verwendungsmöglichkeiten.
Verwenden Sie keine nicht grundlegenden Typwerte wie Objekte oder Arrays als
v-for
fürkey
. Bitte verwenden Sie eine Zeichenfolge oder einen numerischen Wert.
Eine detailliertere Verwendung des key
-Attributs finden Sie in der API-Dokumentation von key
.
Array-Update-Erkennung
Mutationsmethode Methode)
Vue umschließt die Mutationsmethoden des abgehörten Arrays, sodass sie auch Ansichtsaktualisierungen auslösen. Zu diesen verpackten Methoden gehören:
push()
-
pop()
shift()
unshift()
splice()
sort()
reverse()
Sie können die Konsole öffnen und dann das vorherige Beispiel ändern items
Array versucht, die Mutationsmethode aufzurufen. Zum Beispiel example1.items.push({ message: 'Baz' })
.
Array ersetzen
Mutationsmethoden verändern, wie der Name schon sagt, das ursprüngliche Array, auf dem diese Methoden aufgerufen werden. Im Gegensatz dazu gibt es auch nicht mutierende Methoden wie filter()
, concat()
und slice()
. Sie verändern das ursprüngliche Array nicht, wohingegen immer ein neues Array zurückgibt. Wenn Sie den nicht mutierenden Ansatz verwenden, können Sie das alte Array durch das neue ersetzen:
example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
Sie könnten denken, dass dies dazu führen würde, dass Vue das vorhandene DOM verwirft und die gesamte Liste neu rendert. Glücklicherweise ist dies nicht der Fall. Vue implementiert einige intelligente Heuristiken, um die Wiederverwendung von DOM-Elementen zu maximieren. Daher ist das Ersetzen des ursprünglichen Arrays durch ein Array mit denselben Elementen ein sehr effizienter Vorgang.
Notizen
Aufgrund von JavaScript-Einschränkungen kann Vue Kann nicht Änderungen in den folgenden Arrays erkennen:
Wenn Sie ein Array-Element direkt mithilfe eines Index festlegen, zum Beispiel:
vm.items[indexOfItem] = newValue
-
Wann Wenn Sie die Länge des Arrays ändern, zum Beispiel:
vm.items.length = newLength
Zum Beispiel:
var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是响应性的 vm.items.length = 2 // 不是响应性的
Um die erste Art von Problem zu lösen, sind die folgenden zwei Methoden können implementiert werden und vm.items[indexOfItem] = newValue
Derselbe Effekt, löst aber auch Statusaktualisierungen innerhalb des reaktiven Systems aus:
// Vue.set Vue.set(vm.items, indexOfItem, newValue) // Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
Sie können auch die vm.$set
Instanzmethode verwenden, die eine globale Methode istVue.set
Ein Alias für:
vm.$set(vm.items, indexOfItem, newValue)
Um die zweite Art von Problem zu lösen, können Sie verwenden splice
:
vm.items.splice(newLength)
Überlegungen zur Objektänderungserkennung
Es liegt immer noch an JavaScript Einschränkungen, Vue Das Hinzufügen oder Löschen von Objekteigenschaften kann nicht erkannt werden:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的
Vue erlaubt kein dynamisches Hinzufügen reaktiver Eigenschaften auf Stammebene zu bereits erstellten Instanzen. Sie können jedoch reaktive Eigenschaften zu verschachtelten Objekten hinzufügen, indem Sie die Methode Vue.set(object, propertyName, value)
verwenden. Beispielsweise können Sie für:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
ein neues age
-Attribut zum verschachtelten userProfile
-Objekt hinzufügen:
Vue.set(vm.userProfile, 'age', 27)
Sie können auch die vm.$set
-Instanzmethode verwenden, die nur global ist Vue.set
Alias:
vm.$set(vm.userProfile, 'age', 27)
Manchmal müssen Sie einem vorhandenen Objekt möglicherweise mehrere neue Eigenschaften zuweisen, z. B. mithilfe von Object.assign()
oder _.extend()
. In diesem Fall sollten Sie ein neues Objekt mit den Eigenschaften beider Objekte erstellen. Wenn Sie also ein neues Responsive-Attribut hinzufügen möchten, sollten Sie anstelle von
Object.assign(vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })
Folgendes tun:
vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })
Gefilterte/sortierte Ergebnisse anzeigen
Manchmal möchten wir eine gefilterte oder sortierte Version eines Arrays anzeigen, ohne die ursprünglichen Daten tatsächlich zu ändern oder zurückzusetzen. In diesem Fall können Sie eine berechnete Eigenschaft erstellen, die ein gefiltertes oder sortiertes Array zurückgibt.
Zum Beispiel:
<li v-for="n in evenNumbers">{{ n }}</li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
In Fällen, in denen berechnete Eigenschaften nicht anwendbar sind (z. B. in verschachtelten v-for
Schleifen), können Sie eine Methode verwenden:
<li v-for="n in even(numbers)">{{ n }}</li>
data: { numbers: [ 1, 2, 3, 4, 5 ] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }
umv-for
Auch der Wertebereich
v-for
kann akzeptiert werden. In diesem Fall wird die Vorlage entsprechend oft wiederholt.
<div> <span v-for="n in 10">{{ n }} </span> </div>
Ergebnisse:
verwendet auf <template>
v-for
Ähnlich wie v-if
können Sie auch v-for
mit <template>
verwenden, um einen Inhalt mit mehreren Elementen in einer Schleife darzustellen. Zum Beispiel:
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider" role="presentation"></li> </template> </ul>
v-for und v-if Verwenden Sie
. Beachten Sie, dass wir nicht empfehlen,
v-if
undv-for
für dasselbe Element zu verwenden. Weitere Details finden Sie im Style Guide.
Wenn sie sich auf demselben Knoten befinden, hat v-for
eine höhere Priorität als v-if
, was bedeutet, dass v-if
in jeder v-for
-Schleife wiederholt ausgeführt wird. Dieser Prioritätsmechanismus ist nützlich, wenn Sie nur Knoten für einige Elemente rendern möchten, wie zum Beispiel:
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
Der obige Code rendert nur unvollendete Aufgaben.
Und wenn Sie die Ausführung der Schleife bedingt überspringen möchten, können Sie v-if
auf dem äußeren Element platzieren (oder <template>
). Zum Beispiel:
<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li> </ul> <p v-else>No todos left!</p>
wird für Komponenten verwendet v-for
Auf einer benutzerdefinierten Komponente können SieIn diesem Teil wird davon ausgegangen, dass Sie die -Komponente<🎜 bereits verstehen > Relevantes Wissen. Sie können es auch überspringen und später darauf zurückkommen.
wie auf jedem normalen Element verwenden. v-for
<my-component v-for="item in items" :key="item.id"></my-component>
In Version 2.2.0 ist jetzt erforderlich, wenn
v-for
für eine Komponente verwendet wird.key
Es werden jedoch keine Daten automatisch an die Komponente übergeben, da die Komponente über einen eigenen unabhängigen Bereich verfügt. Um die Iterationsdaten an die Komponente zu übergeben, verwenden wir die Requisite:
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id" ></my-component>
Der Grund, warum item
nicht automatisch in die Komponente eingefügt wird, besteht darin, dass dadurch der Betrieb der Komponente eng mit <🎜 gekoppelt wird >. Durch die Klärung der Quelle der Daten einer Komponente kann die Komponente in anderen Situationen wiederverwendet werden. v-for
<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>
Beachten Sie hier das Attribut. Dieser Ansatz ist bei der Verwendung von DOM-Vorlagen unbedingt erforderlich, da nur das
is="todo-item"
-Element innerhalb des<ul>
-Elements als gültiger Inhalt betrachtet wird. Dies erzielt den gleichen Effekt wie<li>
, vermeidet jedoch einige potenzielle Fehler beim Parsen des Browsers. Weitere Informationen finden Sie unter<todo-item>
Anweisungen zum Parsen von DOM-Vorlagen.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 = '' } } })