Heim >Web-Frontend >View.js >Vertieftes Verständnis der Reaktionsprinzipien von Vue
Eines der bemerkenswertesten Merkmale von Vue ist sein unauffälliges Reaktivitätssystem. Die Modellebene (Modell) ist nur ein normales JS-Objekt, und durch dessen Änderung wird die Ansicht (Ansicht) aktualisiert. Dies macht die Zustandsverwaltung sehr einfach und intuitiv, aber es ist wichtig zu verstehen, wie sie funktioniert, um einige häufige Probleme zu vermeiden.
In diesem Artikel werden die zugrunde liegenden Details des reaktionsfähigen Systems von Vue ausführlich vorgestellt.
Änderungen verfolgen
Übergeben Sie ein gewöhnliches JS-Objekt an die Datenoption der Vue-Instanz und konvertieren Sie alle Eigenschaften dieses Objekts mithilfe von Object.defineProperty in Getter/Setter.
Object.defineProperty wird nur von ES5 unterstützt und kann nicht angepasst werden, weshalb Vue keine IE8-Browser unterstützt.
Benutzer können Getter/Setter nicht sehen, aber intern ermöglichen sie Vue, Abhängigkeiten zu verfolgen und Änderungen zu benachrichtigen, wenn auf Eigenschaften zugegriffen und diese geändert werden.
Jede Komponenteninstanz verfügt über ein entsprechendes Watcher-Instanzobjekt, das beim Rendern der Komponente verwendet wird als Abhängigkeit, und wenn dann der Setter der Abhängigkeit aufgerufen wird, wird der Watcher zur Neuberechnung aufgefordert, wodurch die zugehörigen Komponenten aktualisiert werden.
Änderungserkennung
Aufgrund der Einschränkungen von modernem JS (und der Ablehnung von Object.observe) kann Vue das Hinzufügen oder Löschen von Objekteigenschaften nicht erkennen. Da Vue beim Initialisieren der Instanz den Getter/Setter-Konvertierungsprozess für das Attribut durchführt, muss das Attribut im Datenobjekt vorhanden sein, damit Vue es konvertieren kann, damit es reagieren kann.
var vm = new Vue({ data:{ a:1 } }) // `vm.a` 是响应的 vm.b = 2 // `vm.b` 是非响应的
Vue erlaubt kein dynamisches Hinzufügen neuer reaktiver Eigenschaften auf Root-Ebene zu bereits erstellten Instanzen. Es ist jedoch möglich, mithilfe der Methode Vue.set(object, key, value) Antworteigenschaften zu verschachtelten Objekten hinzuzufügen.
Vue.set(vm.someObject, 'b', 2)
Sie können auch die Instanzmethode vm.$set verwenden, die auch ein Alias für die globale Vue.set-Methode ist.
this.$set(this.someObject,'b',2)
Manchmal möchten Sie einem vorhandenen Objekt einige Attribute hinzufügen, z. B. mithilfe der Methode Object.assign() oder _.extend(), um Attribute hinzuzufügen. Neue Eigenschaften, die dem Objekt hinzugefügt werden, lösen jedoch keine Aktualisierung aus. In diesem Fall können Sie ein neues Objekt erstellen, das die Eigenschaften des Originalobjekts und die neuen Eigenschaften enthält.
// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })` this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
Reaktive Eigenschaften deklarieren
Da Vue das dynamische Hinzufügen reaktiver Eigenschaften auf Root-Ebene nicht zulässt, müssen Sie die reaktiven Eigenschaften auf Root-Ebene vor der Initialisierung der Instanz deklarieren, auch wenn es sich nur um einen Nullwert handelt.
var vm = new Vue({ data: { // 声明 message 为一个空值字符串 message: '' }, template: '<div>{{ message }}</div>' }) // 之后设置 `message` vm.message = 'Hello!'
Wenn die Nachricht nicht in der Datenoption deklariert ist, warnt Vue die Rendering-Funktion, dass die Eigenschaft, auf die sie zugreifen möchte, nicht existiert.
Diese Einschränkung hat einen technischen Grund. Sie eliminiert eine Art Randfall im Abhängigkeitsverfolgungssystem und ermöglicht außerdem eine effizientere Ausführung von Vue-Instanzen mithilfe des Typprüfungssystems.
Und es gibt auch einen wichtigen Aspekt im Hinblick auf die Wartbarkeit des Codes: Das Datenobjekt ist wie eine Zusammenfassung des Komponentenstatus im Voraus, wodurch der Komponentencode beim späteren erneuten Lesen leichter verständlich wird Entwickler haben es gelesen.
Asynchrone Update-Warteschlange
Vue führt DOM-Updates asynchron durch. Solange Datenänderungen beobachtet werden, öffnet Vue eine Warteschlange und puffert alle Datenänderungen, die in derselben Ereignisschleife auftreten. Wenn derselbe Watcher mehrmals ausgelöst wird, wird er nur einmal in die Warteschlange verschoben.
Diese Art der Deduplizierung während der Pufferung ist sehr wichtig, um unnötige Berechnungen und DOM-Operationen zu vermeiden. Beim nächsten „Tick“ der Ereignisschleife leert Vue dann die Warteschlange und führt die eigentliche (deduplizierte) Arbeit aus.
Vue versucht intern, natives Promise.then und MutationObserver für asynchrone Warteschlangen zu verwenden. Wenn die Ausführungsumgebung dies nicht unterstützt, wird stattdessen setTimeout(fn, 0) verwendet.
Zum Beispiel, wenn vm.someData='new value' ist. festgelegt ist, wird die Komponente nicht sofort erneut gerendert. Wenn die Warteschlange geleert wird, wird die Komponente beim nächsten „Tick“ aktualisiert, wenn die Ereignisschleifenwarteschlange gelöscht wird. In den meisten Fällen müssen Sie sich über diesen Vorgang keine Gedanken machen, aber wenn Sie nach der Aktualisierung des DOM-Status etwas tun möchten, kann dies etwas knifflig sein.
Obwohl Vue.js Entwickler im Allgemeinen dazu ermutigt, „datengesteuert“ zu denken und den direkten Kontakt mit dem DOM zu vermeiden, gibt es Zeiten, in denen dies erforderlich ist. Um zu warten, bis Vue die Aktualisierung des DOM nach den Datenänderungen abgeschlossen hat, können Sie Vue.nextTick(callback) unmittelbar nach den Datenänderungen verwenden. Diese Rückruffunktion wird aufgerufen, nachdem die DOM-Aktualisierung abgeschlossen ist.
<div id="example">{{message}}</div>
var vm = new Vue({ el: '#example', data: { message: '123' } }) vm.message = 'new message' // 更改数据 vm.$el.textContent === 'new message' // false Vue.nextTick(function () { vm.$el.textContent === 'new message' // true })
Es ist besonders praktisch, die Instanzmethode vm.$nextTick() innerhalb einer Komponente zu verwenden, da sie kein globales Vue erfordert und diese in der Callback-Funktion automatisch an die aktuelle Vue-Instanz gebunden wird:
Vue.component('example', { template: '<span>{{ message }}</span>', data: function () { return { message: '没有更新' } }, methods: { updateMessage: function () { this.message = '更新完成' console.log(this.$el.textContent) // => '没有更新' this.$nextTick(function () { console.log(this.$el.textContent) // => '更新完成' }) } } })
Related Empfehlungen:
Zusammenfassung der Fragen zum Front-End-Vue-Interview 2020 (mit Antworten)
Empfehlung für das Vue-Tutorial: Auswahl der neuesten 5 vue.js-Video-Tutorials für 2020
Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Einführung in die Programmierung! !
Das obige ist der detaillierte Inhalt vonVertieftes Verständnis der Reaktionsprinzipien von Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!