Listenwiedergabe


Verzeichnis


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:

1.jpg

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:

2.jpg

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:

3.jpg

Sie können den zweiten Parameter auch als Eigenschaftsnamen (d. h. Schlüsselnamen) angeben:

<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

4.jpg

Sie können den dritten Parameter auch als Index verwenden:

<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

5.jpg

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ür key. 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:

  1. Wenn Sie ein Array-Element direkt mithilfe eines Index festlegen, zum Beispiel: vm.items[indexOfItem] = newValue

  2. 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:

1.jpg


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 und v-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


In 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.

Auf einer benutzerdefinierten Komponente können Sie

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

Hier ist ein vollständiges Beispiel einer einfachen Aufgabenliste:

<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 = ''
    }
  }
})

1.gif