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

Detaillierte Erklärung der CSS3-Textschatteneigenschaft Textschatten

Textschatten-Textschatten-Eigenschaftseffekte: 1....

JavaScript zählt, wie oft ein Zeichen vorkommt

In diesem Artikelbeispiel wird der spezifische Ja...

Vue verwendet Echart, um Beschriftungen und Farben anzupassen

In diesem Artikelbeispiel wird der spezifische Co...

MySQL-Integritätsbeschränkungen – Definition und Beispiel-Tutorial

Inhaltsverzeichnis Integritätsbeschränkungen Defi...

Javascript zum Umschalten durch Klicken auf das Bild

Durch Klicken Bilder zu wechseln, ist im Leben ei...

Verstehen Sie das elastische CSS3 FlexBox-Layout in 10 Minuten

Grundlegende Einführung Merkmale Flexbox ist ein ...

So schreiben Sie DROP TABLE in verschiedene Datenbanken

So schreiben Sie DROP TABLE in verschiedene Daten...

Detaillierte grafische Erläuterung der MySql5.7.18-Zeichensatzkonfiguration

Hintergrund: Vor langer Zeit (2017.6.5, der Artik...

Ein Artikel zeigt Ihnen, wie Sie den Watch-Listener von Vue verwenden

Inhaltsverzeichnis Hörer beobachten Format Richte...

Verwenden von Shadowsocks zum Erstellen eines transparenten LAN-Gateways

Inhaltsverzeichnis Installieren und konfigurieren...