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

So führen Sie mehrere MySQL-Instanzen unter Windows aus

Vorwort Unter Windows können Sie mehrere MySQL-In...

Implementierungsbeispiel eines Videoplayers basierend auf Vue

Wenn der vorhandene Videoplayer die Anforderungen...

Eine kurze Diskussion über die Rolle von Vue3 defineComponent

Inhaltsverzeichnis defineComponent-Überladungsfun...

Vue realisiert den gesamten Prozess der Slider-Drag-Verifizierungsfunktion

Rendern Definieren Sie das Skelett, schreiben Sie...

CentOS6.8 verwendet cmake zur Installation von MySQL5.7.18

Unter Bezugnahme auf die Online-Informationen hab...

Analyse der Unterschiede zwischen Iframe und FRAME

1. Verwendung des Iframe-Tags <br />Wenn es ...

So optimieren Sie die MySQL-Abfragegeschwindigkeit

In den vorherigen Kapiteln haben wir die Auswahl ...

Grafisches Tutorial zur Installation von Linux CentOS6.9 unter VMware

Als technischer Neuling zeichne ich den Vorgang d...

Lösung zum Vergessen des MySQL-Passworts unter Linux

Das Problem ist folgendes: Ich habe den Befehl my...

Gruselige Halloween-Linux-Befehle

Auch wenn nicht Halloween ist, lohnt es sich, sic...

HTML-Auszeichnungssprache - Referenz

Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...

So stellen Sie mit Navicat Premium eine Remoteverbindung zur MySQL-Datenbank her

Derjenige, der eine neue Verbindung herstellt, en...