Berechnete Eigenschaften und Listener
Verzeichnis
Berechnete Eigenschaften
Ausdrücke in Vorlagen sind sehr praktisch, aber für einfache Vorgänge konzipiert. Wenn einer Vorlage zu viel Logik hinzugefügt wird, kann sie übergewichtig und schwer zu warten sein. Zum Beispiel:
<div id="example"> {{ message.split('').reverse().join('') }} </div>
Hier ist die Vorlage keine einfache deklarative Logik mehr. Man muss eine Weile zuschauen, bis man erkennt, dass man hier den umgedrehten String der Variablen message
anzeigen möchte. Es wird schwieriger, damit umzugehen, wenn Sie die umgedrehte Zeichenfolge hier in der Vorlage mehrmals referenzieren möchten.
Für jede komplexe Logik sollten Sie also berechnete Eigenschaften verwenden.
Grundlegendes Beispiel
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })
Ergebnis:
Original message: "Hello" Computed reversed message: "olleH"
Hier deklarieren wir ein Berechnetes Eigentum reversedMessage
. Die von uns bereitgestellte Funktion wird als Getter-Funktion des Attributs vm.reversedMessage
verwendet:
console.log(vm.reversedMessage) // => 'olleH' vm.message = 'Goodbye' console.log(vm.reversedMessage) // => 'eybdooG'
Sie können die Browserkonsole öffnen und die VM im Beispiel selbst ändern. Der Wert von vm.reversedMessage
hängt immer vom Wert von vm.message
ab.
Sie können berechnete Eigenschaften wie normale Eigenschaften in Vorlagen binden. Vue weiß, dass vm.reversedMessage
von vm.message
abhängt. Wenn sich also vm.message
ändert, werden auch alle Bindungen aktualisiert, die von vm.reversedMessage
abhängen. Und das Beste daran ist, dass wir diese Abhängigkeit deklarativ erstellt haben: Die Getter-Funktion der berechneten Eigenschaft hat keine Nebenwirkungen, was das Testen und Verstehen erleichtert.
Berechneter Eigenschaften-Cache vs Methoden
Sie haben vielleicht bemerkt, dass wir den gleichen Effekt erzielen können, indem wir eine Methode in einem Ausdruck aufrufen:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
Wir können stattdessen dieselbe Funktion als Methode definieren Nicht eine berechnete Eigenschaft. Das Endergebnis ist tatsächlich in beide Richtungen genau das gleiche. Der Unterschied besteht jedoch darin, dass berechnete Eigenschaften basierend auf ihren reaktiven Abhängigkeiten zwischengespeichert werden . Sie werden nur dann neu bewertet, wenn sich die zugehörigen reaktiven Abhängigkeiten ändern. Das bedeutet, dass, solange sich message
nicht geändert hat, mehrere Zugriffe auf die berechnete Eigenschaft reversedMessage
sofort das vorherige Berechnungsergebnis zurückgeben, ohne dass die Funktion erneut ausgeführt werden muss.
Dies bedeutet auch, dass die berechnete Eigenschaft unten nicht mehr aktualisiert wird, da Date.now()
keine reaktive Abhängigkeit ist:
computed: { now: function () { return Date.now() } }
Im Gegensatz dazu wird die aufrufende Methode jedes Mal, wenn ein erneutes Rendern ausgelöst wird, ImmerFühren Sie die Funktion erneut aus.
Warum brauchen wir Caching? Angenommen, wir haben eine aufwendig berechnete Eigenschaft A, die das Durchlaufen eines riesigen Arrays und die Durchführung vieler Berechnungen erfordert. Dann haben wir möglicherweise andere berechnete Eigenschaften, die von A abhängen. Ohne Caching würden wir den Getter von A zwangsläufig mehrmals ausführen! Wenn Sie kein Caching wünschen, verwenden Sie stattdessen Methoden.
Berechnete Eigenschaften vs. Abhöreigenschaften
Vue bietet eine allgemeinere Möglichkeit, Daten zu beobachten und auf sie zu reagieren Änderungen an der Vue-Instanz: Listening-Attribut . Es ist leicht, watch
zu missbrauchen, wenn Sie einige Daten haben, die geändert werden müssen, wenn sich andere Daten ändern – insbesondere, wenn Sie AngularJS zuvor verwendet haben. Allerdings ist es oft besser, berechnete Eigenschaften statt imperativer watch
-Rückrufe zu verwenden. Betrachten Sie dieses Beispiel:
<div id="demo">{{ fullName }}</div>rrree
Der obige Code ist zwingend und repetitiv. Vergleichen Sie dies mit der Version mit berechneten Eigenschaften:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
Viel besser, nicht wahr?
Setter für berechnete Eigenschaften
Berechnete Eigenschaften haben standardmäßig nur Getter, Sie können sie aber auch verwenden sie bei Bedarf. Stellen Sie einen Setter bereit:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } })
Jetzt ausführenvm.fullName = 'John Doe'
, der Setter wird aufgerufen und vm.firstName
und vm.lastName
werden entsprechend aktualisiert.
Listener
Während berechnete Eigenschaften in den meisten Fällen besser geeignet sind, kann es vorkommen, dass a Es ist ein benutzerdefinierter Listener erforderlich. Aus diesem Grund bietet Vue mit der Option watch
eine allgemeinere Möglichkeit, auf Datenänderungen zu reagieren. Dieser Ansatz ist am nützlichsten, wenn Sie bei Datenänderungen asynchrone oder teure Vorgänge ausführen müssen.
Zum Beispiel:
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // ...
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div>
Ergebnis:
In diesem Beispiel können wir mit der Option watch
einen asynchronen Vorgang ausführen (Zugriff auf eine API), begrenzen Sie die Häufigkeit, mit der wir die Operation ausführen, und legen Sie Zwischenzustände fest, bevor wir das Endergebnis erhalten. Dies sind Dinge, die berechnete Eigenschaften nicht leisten können.
Zusätzlich zur Option watch
können Sie auch den Imperativ vm.$watch API verwenden.