Grund: Um zu verhindern, dass mehrere Komponenteninstanzobjekte dieselben Daten teilen und eine Datenverschmutzung in Form einer Funktion verursachen, wird bei Verwendung von initData als Factory-Funktion ein neues Datenobjekt zurückgegeben. Wenn die Daten in der Komponente als Funktion geschrieben werden, werden die Daten in Form eines Funktionsrückgabewerts definiert, sodass bei jeder Wiederverwendung der Komponente neue Daten mit einem eigenen Bereich zurückgegeben werden, ähnlich wie beim Erstellen privater Daten für jede Komponenteninstanz Der Datenraum ermöglicht es jeder Komponenteninstanz, ihre eigenen Daten zu verwalten.
Die Betriebsumgebung dieses Tutorials: Windows7-System, Vue3-Version, DELL G3-Computer.
1. Der Unterschied zwischen Instanz- und Komponentendefinition von Daten
Bei der Definition einer Vue-Instanz kann das Datenattribut entweder ein Objekt oder eine Funktion sein
const app = new Vue({ el:"#app", // 对象格式 data:{ foo:"foo" }, // 函数格式 data(){ return { foo:"foo" } } })
Das in einer Komponente definierte Datenattribut kann nur ein sein Funktion
Wenn die Komponentendaten direkt als Objekt definiert sind
Vue.component('component1',{ template:`<div>组件</div>`, data:{ foo:"foo" }})
, erhalten Sie eine Warnmeldung
Warnhinweis: Die zurückgegebenen Daten sollten in jeder Komponenteninstanz eine Funktion sein
2. Komponentendaten Definitionsfunktion und Der Unterschied zwischen Objekten
Oben wurde erwähnt, dass Komponentendaten eine Funktion sein müssen. Ich frage mich, ob Sie jemals darüber nachgedacht haben, warum das so ist.
Wenn wir eine Komponente definieren, bildet Vue schließlich eine Komponenteninstanz über Vue.extend()
Hier imitieren wir den Komponentenkonstruktor, definieren das Datenattribut und verwenden die Form eines Objekts
function Component(){ } Component.prototype.data = { count : 0 }
Erstellen Sie zwei Komponenteninstanzen
const componentA = new Component() const componentB = new Component()
Ändern Sie den Wert des Datenattributs der Komponente Komponente A, und der Wert in Komponente B ändert sich ebenfalls.
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 1
Der Grund dafür ist, dass beide dieselbe Speicheradresse haben und der von Komponente A geänderte Inhalt sich auch auf Komponente B auswirkt. [Freigabe von Lernvideos: vue-Video-Tutorial, Web-Front-End-Video]
Wenn wir die Form einer Funktion verwenden, tritt diese Situation nicht auf (die Speicheradresse des von der Funktion zurückgegebenen Objekts ist nicht dieselbe )
function Component(){ this.data = this.data() } Component.prototype.data = function (){ return { count : 0 } }
Ändern Sie den Wert des Datenattributs der Komponente A, der Wert in Komponente B ist nicht betroffen
console.log(componentB.data.count) // 0 componentA.data.count = 1 console.log(componentB.data.count) // 0
Die Vue-Komponente kann viele Instanzen haben, und die Funktion wird verwendet, um ein neues Datenformular zurückzugeben, sodass die Daten von Jedes Instanzobjekt wird nicht durch die Daten anderer Instanzobjekte verunreinigt
Speicherort des Quellcodes: /vue-dev/src/core/instance/state .js
function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
...
}
Wenn die Komponente erstellt wird, werden die Optionen zusammengeführt
Speicherort des Quellcodes: /vue-dev/src/core/util/options.js
/vue-dev/src/core/instance/state.js
Vue.prototype._init = function (options?: Object) { ... // merge options if (options && options._isComponent) { // optimize internal component instantiation // since dynamic options merging is pretty slow, and none of the // internal component options needs special treatment. initInternalComponent(vm, options) } else { vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm ) } ... }
data既能是object也能是function,那为什么还会出现上文警告呢?
别急,继续看下文
组件在创建的时候,会进行选项的合并
源码位置:/vue-dev/src/core/util/options.js
自定义组件会进入mergeOptions进行选项合并
strats.data = function ( parentVal: any, childVal: any, vm?: Component ): ?Function { if (!vm) { if (childVal && typeof childVal !== "function") { process.env.NODE_ENV !== "production" && warn( 'The "data" option should be a function ' + "that returns a per-instance value in component " + "definitions.", vm ); return parentVal; } return mergeDataOrFn(parentVal, childVal); } return mergeDataOrFn(parentVal, childVal, vm); };
定义data会进行数据校验
源码位置:/vue-dev/src/core/instance/init.js
rrreee
Daten definieren führt eine Datenüberprüfung durchSpeicherort des Quellcodes: /vue-dev/src/core/instance/init.js
Dies Wenn die VM-Instanz undefiniert ist, geben Sie die if-Beurteilung ein. Wenn der Datentyp keine Funktion ist, wird eine Warnung angezeigt. Die Stamminstanz ist ein Singleton. Es tritt keine Datenverschmutzung auf. Komponenteninstanzobjektdaten müssen eine Funktion sein. Der Zweck besteht darin, zu verhindern, dass mehrere Komponenteninstanzobjekte dieselben Daten teilen und Datenverschmutzung verursachen. Wenn initData als Factory-Funktion verwendet wird, wird ein neues Datenobjekt zurückgegeben. Hinweis:
Die Komponenten in Vue werden zur Wiederverwendung verwendet, um eine Wiederverwendung von Daten zu verhindern. Sie werden als Funktionen definiert.
Die Daten in der Vue-Komponente sollten voneinander isoliert sein und sich nicht gegenseitig beeinflussen. Bei jeder Wiederverwendung der Komponente sollten die Datendaten einmal kopiert werden Wenn die Komponente kopiert wird, sind die Daten anderer wiederverwendeter lokaler Komponenten nicht betroffen. Daher müssen Sie über die Datenfunktion ein Objekt als Status der Komponente zurückgeben.
Wenn wir die Daten in die Komponente als Funktion schreiben, werden die Daten in Form eines Funktionsrückgabewerts definiert, sodass bei jeder Wiederverwendung der Komponente neue Daten mit einem eigenen Gültigkeitsbereich zurückgegeben werden, ähnlich wie bei Durch Angabe jeder Komponenteninstanz wird ein privater Datenraum erstellt, sodass jede Komponenteninstanz ihre eigenen Daten verwalten kann.
Wenn das Datum unserer Komponente einfach in Objektform geschrieben wird, verwenden diese Instanzen denselben Konstruktor. Aufgrund der Eigenschaften von JavaScript teilen alle Komponenteninstanzen dieselben Daten, was zu einer Änderung und allen Änderungen führt.
(Teilen von Lernvideos: Web-Frontend-Entwicklung, Grundlegendes Programmiervideo)
Das obige ist der detaillierte Inhalt vonWarum sind Daten in der Vue-Komponente eine Funktion?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!