Heim >Web-Frontend >View.js >Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

青灯夜游
青灯夜游nach vorne
2023-03-28 19:14:402246Durchsuche

Dieser Artikel wird Ihnen helfen, Vue kennenzulernen und darüber zu sprechen, wie Vue mit reaktionsfähigen Daten umgeht. Hoffe, es hilft allen!

Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Möglicherweise haben Sie große Zweifel an den reaktionsfähigen Daten von Vue.

Warum sollten wir beispielsweise auf Proxy umsteigen?

Warum gibt es beispielsweise zwei APIs, reaktiv und ref?

Wie implementiert Vue beispielsweise Reaktionsfähigkeit?

Tatsächlich sind die Antworten darauf im Quellcode zu finden.

Im ersten Artikel „Was sind die Upgrades von vue3“ habe ich auch die Vorteile der Verwendung von Proxys und die Mängel von Object.defineProperty erwähnt. Aber heute möchte ich den Blickwinkel ändern und chatGPT diese Frage beantworten lassen. [Verwandte Empfehlungen: vuejs-Video-Tutorial, Web-Front-End-Entwicklung]

Nun, ich finde, es ist besser, als ich zusammengefasst habe.

Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Fahren Sie dann mit der nächsten Frage fort.

Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Diese Antwort fühlt sich offizieller an, aber sie gibt mir nicht die Antwort, die ich will.

Der Grund ist eigentlich ganz einfach, denn die Proxy-Methode kann keine Werttypen, sondern nur Objekte vertreten. Daher ist eine zusätzliche Methode erforderlich, um Werttypdaten zu verarbeiten.

Natürlich können Sie auch die Welt mit einem Ref erobern. Wenn der Vue-Quellcode kompatibel ist, wird er automatisch konvertiert.

Mit diesem Verständnis schauen wir uns das heutige Highlight an und imitieren den Vue3-Quellcode ein reaktionsfähiges System implementieren.

Sie können klicken, um den entsprechenden Code anzuzeigen. Wählen Sie einfach verschiedene Zweige entsprechend dem Titel des Artikels aus.

Reaktiv implementieren

Wir haben im vorherigen Artikel auch vorgestellt, dass Reaktiv tatsächlich ein Proxy-Objekt ist.

Wir können Proxy verwenden, um eine einfache reaktive Proxy-Funktion zu implementieren.

      function reactive(target) {        const isObject = (val) =>  val !== null && typeof val === 'object'

        if (!isObject(target)) {          console.warn(`数据必须是对象: ${String(target)}`)          return target
        }        const proxy = new Proxy(target, {          get: (target, key, receiver) => {            console.log('get', key)            const res = Reflect.get(target, key, receiver)            // track(target, key)
            // 这句很关键,不然嵌套数据,里面的不会响应
            if (isObject(res)) {              return reactive(res)
            }            return res
          },          set: (target, key, value, receiver) => {            console.log('set', key, value)            const result = Reflect.set(target, key, value, receiver)            // trigger(target, key, value)
            return result
          },          deleteProperty: () => {            const result = Reflect.deleteProperty(target, key)            return result
          }
        })        return proxy
      }      const person = reactive({        name: '',        age: 18,        like: ['apple']
      })

      person.name  = 'vue test'复制代码

Hinweis: Reflect

Reflect.get(target, key) unterscheidet sich geringfügig vom direkten Zugriff auf target[key].

Wenn im Proxy-Objekt auf get, set usw. verwiesen wird, kann dies umgeleitet werden.

Zum Beispiel:

        const person = new Proxy({            name: "vue test",            age: 18,            get info() {                return 'name is :' + this.name + ' age is:' + this.age
            }
        }, {            get: (target, key, receiver) => {                console.log('get', key)                // return target[key]
                return Reflect.get(target, key, receiver)
            }
        })        console.log(person.info)复制代码

Mit Reflect können wir es auslösen, wenn wir auf Name und Alter zugreifen. Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Nach dem Wechsel zum Ziel wird es nur einmal in der Info ausgelöst.

return target[key]复制代码

Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

Ref implementieren

In vue3 wird ref durch get und set implementiert.

Ähnlich wie oben deklarieren wir immer noch zuerst eine Funktion und greifen dann über get und set auf die Daten zu.

      function ref(value) {        return new RefImpl(value)
      }      class RefImpl {        constructor(value) {          // 如果值是对象,则用reactive处理
          this._value = isObject(value) ? reactive(value) : value          // 记录一下初始值
          this._rawValue = value
        }        get value() {          // trackRefValue(this)
          return this._value
        }        set value(newVal) {          if (!Object.is(newVal, this._rawValue)) {            // 更新原始数据
            this._rawValue = newVal            // 更新 .value 的值
            this._value = isObject(newVal) ? reactive(newVal) : value            // triggerRefValue(this)
          }
        }
      }复制代码

Der Quellcode erklärt auch sehr intuitiv, warum ref in .value verwendet werden muss, da get/set über value festgelegt wird.

Abhängigkeitserfassung und -auslösung hinzufügen

Wir haben den Datenproxy fertiggestellt, aber wie benachrichtigen wir die Komponente nach den Datenänderungen, um eine bidirektionale Bindung zu implementieren?

Die Antwort besteht darin, sich auf das Sammeln und Auslösen zu verlassen. Wenn Get ausgelöst wird, speichere ich die Bedingung, die Get auslöst, und führe sie einfach erneut aus, um die Bedingung auszulösen. .

Schauen wir uns den Code noch einmal an. Ich füge eine Track-Collection-Methode und eine Target-Trigger-Methode hinzu. (Das heißt, die beiden im obigen Codeausschnitt auskommentierten Codezeilen)

Zusätzlich ist eine Effektfunktion erforderlich, um die Triggerfunktion zu verwalten.

      let activeEffect = null
      const targetMap = new WeakMap()      // 依赖收集/触发
      function track(target, key) {        let depsMap = targetMap.get(target)        if (!depsMap) {
          targetMap.set(target, (depsMap = new Map()))
        }        let dep = depsMap.get(key)        if (!dep) {
          dep = new Set()
        }
        dep.add(activeEffect)
        depsMap.set(key, dep)
      }      function trigger(target, key, value) {        const depsMap = targetMap.get(target)        if (!depsMap) {          return
        }        const deps = depsMap.get(key)        if (!deps) {          return
        }

        deps.forEach(effectFn => {          if (effectFn.scheduler) {
            effectFn.scheduler()
          } else {            effectFn()
          }
        })
      }      function effect(fn,options = {}) {        const effectFn = () => {          try {
            activeEffect = effectFn            return fn()
          } catch (error) {
            activeEffect = null
          }
        }        if (!options.lazy) {          effectFn()
        }
        effectFn.scheduler = options.scheduler
        return effectFn
      }      const person = reactive({        name: "hello world"
      })      effect(() => {        console.log('effect person', person.name)
      })      setTimeout(() => {
        person.name = 'setTimeout world'
      }, 2000)复制代码

activeEffect wird zum Speichern von Triggerbedingungsfunktionen verwendet.

targetMap wird zum Speichern des Abhängigkeitswörterbuchs verwendet. Das Format ist wie folgt:

{
    target: {
        key: []
    }
}复制代码
. Das Ausgabeergebnis ist Hallo Welt. Nach 2 Sekunden wird die Abhängigkeitsfunktion erneut ausgeführt und setTimeout world wird ausgegeben Der Proxy der Daten ist nicht kompliziert. Auf der Basis des Proxys wird eine gewisse Grenzverarbeitung hinzugefügt. Um Reaktionsfähigkeit zu erreichen, müssen Sie eine Abhängigkeitssammlung und eine Implementierung zur Abhängigkeitsauslösung hinzufügen.

effect ist eine sehr wichtige Funktion. Viele APIs werden basierend auf dieser Funktion entwickelt, wie zum Beispiel useEffect und watch. Die Aktualisierung der Komponenten basiert auch auf der Effektfunktion, die später erwähnt wird.

Wenn Sie den Effekt nicht verstehen, können Sie die Ausführungsreihenfolge klären. Eine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten

  • 1. Rufen Sie die Effektfunktion auf und übergeben Sie den Parameter fn
  • 2. Deklarieren Sie eine effectFn-Funktion, führen Sie sie aus und speichern Sie die Funktion als activeEffect
  • 3. Führen Sie fn aus und lesen Sie person.name
  • 4. Verwenden Sie den Get-Proxy des Proxys
  • 5. Sammeln Sie Abhängigkeiten und speichern Sie die von activeEffect gespeicherte Funktion in der globalen Karte
  • 6. Zu diesem Zeitpunkt wird die Effektfunktion ausgeführt und wartet auf die Datenaktualisierung
  • 7.2s Verwenden Sie abschließend den Set-Agenten des Proxys
  • 8. Führen Sie die in der globalen Karte gespeicherte Funktion aus, führen Sie die Effektfunktion erneut aus und kehren Sie erneut zu Schritt 1 zurück

Sie können zum Anzeigen klicken Geben Sie den entsprechenden Code ein und wählen Sie den Zweig Lektion3 aus.

Der mit dem Artikel verbundene Code kann unter vue/examples angezeigt werden, und die nachgeahmte Vue-Implementierungsversion kann unter Pakete/Reaktivität angezeigt werden.

(Teilen von Lernvideos: Vuejs-Einführungs-Tutorial, Grundlegendes Programmiervideo)

Das obige ist der detaillierte Inhalt vonEine eingehende Analyse der Methode von Vue zur Verarbeitung responsiver Daten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen