In diesem Artikel werden hauptsächlich die grundlegenden Ideen zur Implementierung der Vue2.0-Reaktionsfähigkeit vorgestellt. Jetzt teile ich ihn mit Ihnen und gebe Ihnen eine Referenz.
Ich habe kürzlich den vue2.0-Quellcode über die Implementierung von Reaktionsfähigkeit gelesen. Der folgende Blog-Beitrag wird die Implementierungsideen von vue2.0 über Reaktionsfähigkeit durch einfachen Code wiederherstellen.
Beachten Sie, dass dies nur eine Wiederherstellung der Implementierungsidee ist. Die Implementierung verschiedener Details, wie z. B. die Überwachung von Datenoperationen in Arrays und die Objektverschachtelung, wird in diesem Beispiel nicht behandelt Für eine detailliertere Implementierung können Sie mehr darüber erfahren, indem Sie den Quellcode-Beobachterordner und die Statusdatei im Instanzordner lesen.
Zuerst definieren wir die Struktur des Vue-Objekts
class Vue { constructor(options) { this.$options = options; this._data = options.data; this.$el = document.querySelector(options.el); } }
Schritt 1: Ändern Sie die Eigenschaften unter Daten in „observable“
Verwenden Sie Object .defineProperty-Monitore Die Attribute get und set des Datenobjekts werden aufgerufen, wenn Daten gelesen und zugewiesen werden. Auf diese Weise kann die Zuweisung mit dem häufigsten Gleichheitszeichen ausgelöst werden.
//数据劫持,监控数据变化 function observer(value, cb){ Object.keys(value).forEach((key) => defineReactive(value, key, value[key] , cb)) } function defineReactive(obj, key, val, cb) { Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ return val }, set: newVal => { if(newVal === val) return val = newVal } }) }
Schritt 2: Implementieren Sie einen Nachrichtenabonnenten
Es ist ganz einfach. In dieses Array fügen wir den Abonnenten ein Rufen Sie einfach Ihre eigene Update-Methode auf
class Dep { constructor() { this.subs = [] } add(watcher) { this.subs.push(watcher) } notify() { this.subs.forEach((watcher) => watcher.cb()) } }
Jedes Mal, wenn die Set-Funktion aufgerufen wird, lösen wir eine Benachrichtigung aus, um das Update zu implementieren
Dann kommt das Problem. Wer sind Abonnenten? Ja, es ist Watcher. . Sobald dep.notify() die Abonnenten, also den Watcher, durchläuft, ruft er seine update()-Methode auf
function defineReactive(obj, key, val, cb) { const dep = new Dep() Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ return val }, set: newVal => { if(newVal === val) return val = newVal dep.notify() } }) }
Schritt 3: Implementieren Sie einen Watcher
Watcher Die Implementierung ist relativ einfach. Tatsächlich ist es der Vorgang, den wir ausführen müssen, wenn wir Datenänderungen durchführen
class Watcher { constructor(vm, cb) { this.cb = cb this.vm = vm } update(){ this.run() } run(){ this.cb.call(this.vm) } }
Schritt 4: Berühren Sie, um die Abhängigkeit zu erhalten
Wir haben das erreicht Die oben genannten drei Schritte: Datenänderungen können Aktualisierungen auslösen, aber das Problem besteht jetzt darin, dass wir den Beobachter nicht mit unseren Daten verknüpfen können.
Wir wissen, dass, nachdem das Attribut für Daten auf „defineReactive“ gesetzt wurde, eine Änderung des Werts für Daten das Setzen auslöst. Wenn wir dann den oberen Datenwert übernehmen, wird get ausgelöst. Sie können dies also nutzen und zunächst die folgende Renderfunktion ausführen, um zu erfahren, welche Datenunterstützung erforderlich ist, um die Ansicht zu aktualisieren und sie als Abonnent der Daten aufzuzeichnen.
function defineReactive(obj, key, val, cb) { const dep = new Dep() Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ if(Dep.target){ dep.add(Dep.target) } return val }, set: newVal => { if(newVal === val) return val = newVal dep.notify() } }) }
Schließlich schauen wir uns die Verwendung eines Proxys an, um unseren Datenzugriff an das Vue-Objekt zu binden
_proxy(key) { const self = this Object.defineProperty(self, key, { configurable: true, enumerable: true, get: function proxyGetter () { return self._data[key] }, set: function proxySetter (val) { self._data[key] = val } }) } Object.keys(options.data).forEach(key => this._proxy(key))
Das Folgende ist der vollständige Code der gesamten Instanz
class Vue { constructor(options) { this.$options = options; this._data = options.data; this.$el =document.querySelector(options.el); Object.keys(options.data).forEach(key => this._proxy(key)) observer(options.data) watch(this, this._render.bind(this), this._update.bind(this)) } _proxy(key) { const self = this Object.defineProperty(self, key, { configurable: true, enumerable: true, get: function proxyGetter () { return self._data[key] }, set: function proxySetter (val) { self._data[key] = val } }) } _update() { console.log("我需要更新"); this._render.call(this) } _render() { this._bindText(); } _bindText() { let textDOMs=this.$el.querySelectorAll('[v-text]'), bindText; for(let i=0;idefineReactive(value, key, value[key] , cb)) } function defineReactive(obj, key, val, cb) { const dep = new Dep() Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ if(Dep.target){ dep.add(Dep.target) } return val }, set: newVal => { if(newVal === val) return val = newVal dep.notify() } }) } function watch(vm, exp, cb){ Dep.target = new Watcher(vm,cb); return exp() } class Watcher { constructor(vm, cb) { this.cb = cb this.vm = vm } update(){ this.run() } run(){ this.cb.call(this.vm) } } class Dep { constructor() { this.subs = [] } add(watcher) { this.subs.push(watcher) } notify() { this.subs.forEach((watcher) => watcher.cb()) } } Dep.target = null; var demo = new Vue({ el: '#demo', data: { text: "hello world" } }) setTimeout(function(){ demo.text = "hello new world" }, 1000)
Oben ist die gesamte Idee des gesamten datengesteuerten Teils von Vue. Wenn Sie mehr über die Implementierung im Detail erfahren möchten, empfiehlt es sich, einen tieferen Blick auf diesen Teil des Vue-Codes zu werfen.
Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.
Verwandte Artikel:
Verwenden Sie vue+element-ui+ajax, um ein Beispiel einer Tabelle zu implementieren
Lösen Sie das Problem, dass Browser niedrigerer Versionen den Import von es6 nicht unterstützen
Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Reaktionsfähigkeit von vue2.0 (ausführliches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!