Vue2.x-Reaktionsfähigkeit – einfache Erklärung und Beispiele

Vue2.x-Reaktionsfähigkeit – einfache Erklärung und Beispiele

1. Überprüfen Sie die Vue-Responsive-Nutzung

​ Die Reaktionsfähigkeit von Vue ist uns allen vertraut. Wenn wir die Eigenschaften im Datenobjekt in Vue ändern, ändert sich die Stelle, an der auf der Seite auf die Eigenschaft verwiesen wird, entsprechend. Dadurch müssen wir DOM nicht betreiben und keine Datenbindung durchführen.

2. Analyse der Vue-Responsive-Implementierung

Zum Responsive-Prinzip von Vue finden Sie auf der offiziellen Website eine Textbeschreibung unter https://cn.vuejs.org/v2/guide/reactivity.html.

Vue wird hauptsächlich durch Datenentführung und Beobachtermodus implementiert

Datendiebstahl:

vue2.x verwendet intern Object.defineProperty https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Von vue3.x intern verwendeter Proxy https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Beobachtermuster: https://www.jb51.net/article/219790.htm

Internes Mitgliederdiagramm

Funktionen jedes Mitglieds

Ausblick:

Fügen Sie die Mitglieder in den Daten in die Vue-Instanz ein und konvertieren Sie die Mitglieder in den Daten in Getter und Setter

Beobachter:

Überwachen Sie einfache Daten und Objekte im Datenobjekt und benachrichtigen Sie Dep, wenn sich die Daten ändern

Zusammensteller:

Analysieren Sie den Anweisungs-/Differenzausdruck in jedem Element und ersetzen Sie ihn durch die entsprechenden Daten

Abt.:

Benachrichtigung im Beobachtermodus, Beobachter hinzufügen und Beobachter benachrichtigen, wenn sich Daten ändern

Beobachter:

Jeder Ort, der auf eine Eigenschaft in Daten verweist, verfügt über ein Watcher-Objekt, das für die Aktualisierung der Ansicht verantwortlich ist.

Anhang: Die Eigenschaften im Datenobjekt fungieren als beobachtete und der Ort, an dem die Eigenschaften im Datenobjekt referenziert werden, fungiert als Beobachter

3. Implementierung des responsiven Vue-Quellcodes

Vue-Objektimplementierung

Funktion

  • Verantwortlich für die Annahme von Initialisierungsparametern
  • Einfügen der Attribute in Daten in die Dateninstanz und Konvertieren dieser in Getter und Setter
  • Rufen Sie Observer auf, um Änderungen aller Attribute in Daten zu überwachen
  • Rufen Sie den Compiler auf, um Anweisungen und Differenzausdrücke zu analysieren.
Klasse Vue{
    Konstruktor(Optionen){
        // 1. Speichern Sie die übergebenen Attribute über Attribute this.$options= options||{};
        dies.$data= options.data||{};
        dies.$el = Typ von options.el ==='Zeichenfolge' ? document.querySelector(options.el) : options.el;
        // 2. Konvertiere die Daten im Datenparameter in Getter und Setter und mounte sie auf der Vue-Instanz this._proxyData(this.$data)
        // 3. Rufen Sie das Observer-Objekt auf, um Änderungen in den Daten zu überwachen. new Observer(this.$data)
        // 4. Rufen Sie das Compilerobjekt auf, um die Seite zu rendern new Compiler(this)
    }
    _proxyData(Daten){
        wenn (Daten&&Objekt.Schlüssel(Daten).Länge>0){
             für (const Schlüssel in Daten) {
                Objekt.defineProperty(dieser,Schlüssel,{
                    konfigurierbar:true,
                    aufzählbar:wahr,
                    erhalten(){
                        Daten zurückgeben [Schlüssel]
                    },
                    setze(Wert){
                        wenn (Daten[Schlüssel]===Wert) {
                            zurückkehren;
                        }
                        Daten[Schlüssel]=Wert;
                    }
                })
             }
        }
    }
}

Implementierung des Observer-Objekts

Funktion

  • Entführen Sie die Attribute in der Datenoption
  • Wenn ein Attribut in Daten auch ein Objekt ist, konvertieren Sie es rekursiv in ein responsives Objekt
  • Senden Sie Benachrichtigungen, wenn sich Daten ändern
 //Datenentführungsklasse Observer {
    Konstruktor(Daten) {
        dies.walk(Daten)
    }
    gehe(Daten) { 
        //1. Bestimmen Sie, ob Daten ein Objekt sind, wenn (!data || typeof data !== 'object') {     
            zurückkehren
        }
        //2. Schleifenaufruf defineReactive zum Entführen von dataObject.keys(data).forEach(key => {
            this.defineReactive(Daten, Schlüssel, Daten[Schlüssel])
        })
    }
    defineReactive(Objekt, Schlüssel, Wert) {
        //Benachrichtigung erstellen const dep = new Dep()
        //Verwenden Sie walk, um die Eigenschaften im referenzierten Objekt responsiv zu machen this.walk(val)
        const das=dies;
        Objekt.defineProperty(Objekt, Schlüssel, {
            konfigurierbar: true,
            aufzählbar: wahr,
            erhalten() {
                //Notifier sammelt Beobachter Dep.target && dep.addSub(Dep.target)
                Rückgabewert;
            },
            setze(neuerWert) {
                wenn (neuerWert === Wert) {
                    zurückkehren;
                }
                val = neuerWert;
                das.gehen(neuerWert)
                //Wenn sich das beobachtete Objekt ändert, sendet das Notifier-Objekt eine Benachrichtigung an jeden Beobachter dep.notify()
            }
        })
    }
}

Objektimplementierung kompilieren

Funktion

  • Verantwortlich für das Kompilieren von Vorlagen, Parsing-Anweisungen und Differentialausdrücken
  • Verantwortlich für das erste Rendering der Seite
  • Verantwortlich für das erneute Rendern der Ansicht, wenn sich die Daten ändern
 // Compilerklasse Compiler {
    Konstruktor(vm) {
        dies.el = vm.$el;
        dies.vm = vm;
        dies.kompilieren(dieses.el)
    }
    //Vorlage kompilieren um zu bestimmen ob der Knoten ein Textknoten oder ein Elementknoten ist compile(el) {
        let childNodes = el.childNodes;
        //Verarbeite die erste Ebene der untergeordneten Knoten Array.from(childNodes).forEach(node ​​​​=> {
            wenn (dieser.istTextNode(Knoten)) {
                this.compileText(Knoten)
            } sonst wenn (this.isElementNode(node)) {
                this.compileElement(Knoten)
            }
            //Wenn der aktuelle Knoten untergeordnete Knoten hat, rufen Sie rekursiv die Kompilierungsanweisung auf, wenn (node.childNodes && node.childNodes.length) {
                dies.kompilieren(Knoten)
            }
        })
    }

    //Element node kompilieren, Ablaufanweisung compileElement(node) {  
        //Alle Anweisungen durchlaufen Array.from(node.attributes).forEach(attr => {
            //Beurteilen, ob es sich um einen Direktivknoten handelt, if (this.isDirective(attr.name)) {
                const nodeName = attr.name;
                const Schlüssel = attr.nodeValue;
                const-Direktive = nodeName.substr(2)
                this.updater(Anweisung,Knoten,Schlüssel)
            }
        }) 
    }
    updater(Direktive,Knoten,Schlüssel){
        const updaterFn = this[Anweisung+"Updater"]
        updaterFn und updaterFn.call(dieser,Knoten,dieser.vm[Schlüssel],Schlüssel)
    }
    //v-text
    textUpdater(Knoten,Wert,Schlüssel){
        node.textContent=Wert
        //Der Ort, an dem der v-Text-Ausdruck verwendet wird, ist ein Beobachter new Watcher(this.vm,key,newValue => {
            node.textContent = neuerWert
        })
    }
    //v-Modell
    modelUpdater(Knoten,Wert,Schlüssel){
        node.value =Wert
        //Der Ort, an dem der v-Modell-Ausdruck verwendet wird, ist ein Beobachter new Watcher(this.vm,key,newValue => {
            node.value = neuerWert
        })
      //Zweiwegebindung realisierennode.addEventListener('input',()=>{
            this.vm[Schlüssel] = Knoten.Wert
        })
    }
    //v-html
    htmlUpdater(Knoten,Wert,Schlüssel){
        node.innerHTML = Wert
        //Der Ort, an dem der v-html-Ausdruck verwendet wird, ist ein Beobachter new Watcher(this.vm,key,newValue => {
            node.innerHTML = neuerWert
        })
    }

    //Differenzausdruck verarbeiten compileText(node) {
        //Unterschied bei der Übereinstimmung mit regulären Ausdrücken let reg = /\{\{(.+?)\}\}/
        //Verwenden Sie reguläre Ausdrücke, um den Textinhalt des Knotens abzugleichen, und ersetzen Sie ihn, wenn er übereinstimmt, if (reg.test(node.textContent)) {
            //Holen Sie sich den Schlüssel des Interpolationsausdrucks
            lass Schlüssel = RegExp.$1;
            let Wert = node.textContent;
            node.textContent = Wert.ersetzen(reg, this.vm[Schlüssel])

            //Die Stelle, an der der Differenzausdruck verwendet wird, ist ein Beobachter new Watcher(this.vm,key,newValue => {
                node.textContent = neuerWert
            })
        }
    }

    //Ist es eine Direktive? isDirective(attrName) {
        returniere attrName.startsWith('v-')
    }

    //Ist es ein Textknoten? isTextNode(node) {
        Knotentyp zurückgeben === 3
    }

    //Ist es ein Element isElementNode(node) {
        Knoten.Knotentyp zurückgeben === 1
    }
}

Implementierung des Dep-Objekts

Funktion

  • Abhängigkeiten sammeln und Beobachter hinzufügen
  • Alle Beobachter benachrichtigen
 //Notifier-Klasse class Dep {
    Konstruktor() {
        //Speicherbeobachter this.subs = []
    }

    /**
     * Beobachter sammeln */
    Sub hinzufügen(sub) {
        wenn (sub und sub.update) {
            dies.subs.push(sub)
        }
    }

    /**
     * Beobachter über Statusänderungen benachrichtigen */
    benachrichtigen() {
        dies.subs.forEach(sub => {
            unter.update()
        })
    }
}

Implementierung des Watcher-Objekts

Funktion

  • Wenn sich die Daten ändern, benachrichtigt Dep alle Watcher-Instanzen, um die Ansicht zu aktualisieren.
  • Fügt sich beim Instanziieren selbst zum Dep-Objekt hinzu
 //Beobachterklasse class Watcher {
    Konstruktor (vm, Schlüssel, cb) {
        //Vue-Instanz this.vm =vm;
        //Schlüsselobjekt in Daten this.key =key;
        // Rückruffunktion zum Aktualisieren der Ansicht this.cb = cb
        //Speichern Sie die aktuelle Beobachterinstanz in der statischen Zieleigenschaft von Dep Dep.target = this
        //Löse die Getter-Methode von Observe aus und speichere die aktuelle Instanz in Dep.subs //Der alte Wert, der dem Schlüssel in den Daten entspricht this.oldValue = this.vm[this.key]
        Dep.target = null
    }
    //Jeder Beobachter hat eine Update-Methode um den Status zu ändern update(){
        const neuerWert = diese.vm[diese.Schlüssel]
        wenn ( dieser.neuerWert === dieser.alterWert ) {
            zurückkehren
        }
        this.cb(neuerWert)
    }
}

prüfen

<Kopf>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-kompatibel" content="IE=edge">
    <meta name="viewport" content="width=Gerätebreite, Anfangsmaßstab=1.0">
    <Titel>Index</Titel>
    <script src="./js/dep.js"></script>
    <script src="./js/watcher.js"></script>
    <script src="./js/compiler.js"></script>
    <script src="./js/observer.js"></script>
    <script src="./js/vue.js"></script>
</Kopf>
<Text>
    <p id="App">
        <h1>Differenzausdruck</h1>
        <h3>{{msg}}</h3>
        <h3>{{Anzahl}}</h3>
        <h1>v-text</h1>
        <p v-text='Nachricht'></p>
        <h1>V-Modell</h1>
        <Eingabetyp="Text" v-Modell="Nachricht" attr="Nachricht">
        <Eingabetyp="Text" v-Modell="Anzahl">
        <h1>v-html</h1>
        <p v-html="htmlText"></p>
    </p>
    <Skript>
        lass vm = neues Vue({
            el:"#app",
            Daten:{
                msg:'Informationen',
                Anzahl: 'Menge', 
		Person: {Name: 'Name'},
                htmlText:"<p style='color:red'>Hallo</p>"
            }
        })
    </Skript>
</body>

Damit ist dieser Artikel über die einfache Erklärung und Beispiele zur Reaktionsfähigkeit von Vue2.x abgeschlossen. Weitere relevante Inhalte zur Reaktionsfähigkeit von Vue2.x finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Asynchrone Warteschlange des Vue2-Responsive-Systems
  • Einführung in das Vue2 Responsive System
  • Vue2 - reaktionsschnelles Systemzweigwechseln
  • Verschachtelung des Vue2-Responsive-Systems
  • Vue2-Responsive-System: Tiefe Reaktion
  • Vue2-Responsive-System-Array
  • Vue2-Responsive-System festlegen und löschen
  • Nachteile der Reaktionsfähigkeit von Vue2

<<:  MySQL-Datenbank implementiert MMM-Hochverfügbarkeitsclusterarchitektur

>>:  So erstellen Sie einen Nginx-Image-Server mit Docker

Artikel empfehlen

Schritte zur Bereitstellungsmethode für Docker Stack für Webcluster

Docker wird immer ausgereifter und seine Funktion...

MySQL-Paket für Abfrage ist zu groß – Problem und Lösung

Problembeschreibung: Fehlermeldung: Ursache: com....

Einführung in die Verwendung des http-equiv-Attributs im Meta-Tag

Meta ist ein Hilfstag im Kopfbereich der HTML-Spra...

Detaillierte Erklärung des JSON-Dateischreibformats

Inhaltsverzeichnis Was ist JSON Warum diese Techn...

Zusammenfassung ungewöhnlicher JS-Operationsoperatoren

Inhaltsverzeichnis 2. Komma-Operator 3. JavaScrip...

So zeigen Sie den Prozentsatz und die ersten paar Prozent in MySQL an

Inhaltsverzeichnis Erfordern Implementierungscode...

HTML-Zeichnungsbenutzer-Registrierungsseite

In diesem Artikel wird der spezifische Implementi...

Eine detaillierte Einführung in den Lade- und Analyseprozess von HTML-Seiten

Die Reihenfolge, in der der Browser HTML lädt und ...

So verwenden Sie async await elegant in JS

Inhaltsverzeichnis $.ajax von jQuery Der Beginn d...