Beantworten Sie das Caching-Prinzip von Keep-Alive-Komponenten aus Sicht des Quellcodes

Beantworten Sie das Caching-Prinzip von Keep-Alive-Komponenten aus Sicht des Quellcodes

Kommen wir heute gleich zur Sache und sprechen über eine Frage, die mir in einem Interview gestellt wurde: das Caching-Prinzip der Keep-Alive-Komponente.

Offizielle API-Einführung und -Verwendung

  • <keep-alive> Beim Umschließen einer dynamischen Komponente werden inaktive Komponenteninstanzen zwischengespeichert, anstatt zerstört zu werden.
  • Ähnlich wie <transition> ist <keep-alive> eine abstrakte Komponente: Es rendert selbst kein DOM-Element und erscheint auch nicht in der übergeordneten Komponentenkette der Komponente.
  • Wenn eine Komponente in den <Keep-Alive>-Zustand versetzt wird, werden ihre aktivierten und deaktivierten Lifecycle-Hook-Funktionen entsprechend ausgeführt.

Das Beispiel auf der offiziellen Website zeigt, dass das Wechseln zwischen Registerkarten die Vorgänge des Benutzers speichert. In der Praxis kann es auch vorkommen, dass Sie von einer Listenseite zu einer Detailseite und dann wieder zurück zur Listenseite springen. Sie müssen die Filtervorgänge des Benutzers speichern, was die Verwendung von <Keep-Alive> erfordert, wodurch auch ein erneutes Rendern vermieden und die Seitenleistung verbessert werden kann.

Erklärung zu Verwendung und Requisiten

// Verwendung der Keep-Alive-Komponente mit dynamischer Komponente. Weitere Verwendungsmöglichkeiten finden Sie auf der offiziellen Website <keep-alive
 include="['KomponentennameA', 'KomponentennameB']"
 exclude="'KomponentennameC'"
 :max="10">
 <Komponente: ist = "Ansicht"></Komponente>
</am Leben erhalten>

  • include - Zeichenfolge oder regulärer Ausdruck oder Array, Komponenten mit übereinstimmendem Namen werden zwischengespeichert
  • Ausschließen - Zeichenfolge oder regulärer Ausdruck oder Array, Komponenten mit übereinstimmendem Namen werden nicht zwischengespeichert
  • max - Zeichenfolge oder Zahl, die maximale Anzahl zwischengespeicherter Komponenteninstanzen. Instanzen, auf die am längsten nicht zugegriffen wurde, werden gelöscht.

Beachten:

  • <keep-alive> rendert nur eine Komponente in seiner direkten Zeile. Wenn Sie also v-for in <keep-alive> verwenden, funktioniert es nicht. Dasselbe gilt, wenn mehrere Bedingungen vorhanden sind, die die Bedingungen erfüllen.
  • Wenn „Include“ und „Exclude“ übereinstimmen, wird zuerst die Namensoption der Komponente geprüft. Wenn die Namensoption nicht verfügbar ist, wird ihr lokal registrierter Name (d. h. der Schlüsselwert der Komponentenoption der übergeordneten Komponente) abgeglichen. Anonyme Komponenten können nicht zugeordnet werden.
  • <keep-alive> funktioniert mit funktionalen Komponenten nicht richtig, da diese keine Instanzen zwischenspeichern.

Quellcode-Interpretation

Posten Sie zuerst ein Bild des Quellcodes

Insgesamt sind es 125 Reihen, und wenn man sie weglegt, sieht man, dass es gar nicht so viele Dinge sind. Zu Beginn werden einige erforderliche Methoden vorgestellt und dann einige Methoden definiert, die die Keep-Alive-Komponente selbst verwenden wird. Schließlich wird eine Komponentenoption namens Keep-Alive nach außen offengelegt. Mit Ausnahme von Abstract sind uns alle diese Optionen bekannt. Unter ihnen ist die Renderfunktion der wichtigste Teil des Cache-Prinzips. Es ist auch ersichtlich, dass die Keep-Alive-Komponente eine funktionale Komponente ist.

// Die Funktion isRegExp ermittelt, ob es sich um einen regulären Ausdruck handelt, und remove entfernt ein Mitglied im Array. // getFirstComponentChild ruft die erste gültige Komponente des VNode-Arrays ab. import { isRegExp, remove } from 'shared/util'
importiere { getFirstComponentChild } von 'core/vdom/helpers/index'
​
Typ VNodeCache = { [Schlüssel: Zeichenfolge]: ?VNode }; // Cache-Typ der Cache-Komponente VNode​
// Den Komponentennamen anhand des Komponentennamens oder des Komponententags ermitteln (der zweite oben erwähnte Punkt)
Funktion getComponentName (Optionen: ?VNodeComponentOptions): ?string {
 Optionen zurückgeben && (opts.Ctor.options.name || opts.tag)
}
​
// Bestimmen Sie, ob „include“ oder „exclude“ mit dem Komponentennamen übereinstimmt. Funktion stimmt überein (Muster: Zeichenfolge | RegExp | Array<Zeichenfolge>, Name: Zeichenfolge): Boolean {
 wenn (Array.isArray(Muster)) {
 return pattern.indexOf(name) > -1 // include oder exclude ist ein Array} else if (typeof pattern === 'string') {
 return pattern.split(',').indexOf(name) > -1 // include oder exclude ist ein String } else if (isRegExp(pattern)) {
 return pattern.test(name) // include oder exclude ist ein regulärer Ausdruck}
 return false // Keiner von ihnen stimmt überein (beachten Sie den zweiten und dritten Punkt oben)
}
​
// Cache zerstören Funktion pruneCache (keepAliveInstance: any, filter: Function) {
 const { cache, keys, _vnode } = keepAliveInstance // Keep-Alive-Komponenteninstanz für (const key im Cache) {
 const cachedNode: ?VNode = cache[key] // Komponente, die zwischengespeichert wurde if (cachedNode) {
  Konstantname: ?string = getComponentName(cachedNode.componentOptions)
  // Wenn der Name existiert und nicht mit „include“ oder „exclude“ übereinstimmt, zerstöre die zwischengespeicherte Komponente, wenn (name && !filter(name)) {
  pruneCacheEntry(Cache, Schlüssel, Schlüssel, _vnode)
  }
 }
 }
}
​
//Zerstöre den Cache-Eintrag Funktion pruneCacheEntry (
 Cache: VNodeCache,
 Schlüssel: Zeichenfolge,
 Schlüssel: Array<string>,
 aktuell?: VNode
) {
 const cached = cache[key] // Zwischengespeicherte Komponente // „Ob das Zwischenspeichern von Komponenten fortgesetzt werden soll“, wenn eine Änderung vorliegt // Wenn die Komponente zwischengespeichert wurde und die aktuelle Komponente nicht existiert oder das Tag der zwischengespeicherten Komponente nicht mit dem Tag der aktuellen Komponente übereinstimmt, if (cached && (!current || cached.tag !== current.tag)) {
 // Dies bedeutet, dass die Komponente nicht mehr zwischengespeichert werden muss. Zerstöre die Komponenteninstanz cached.componentInstance.$destroy()
 }
 cache[key] = null // Setzt diese Komponente im Cache auf null
 remove(keys, key) // Entferne den Schlüssel dieser Komponente aus dem keys-Array}
​
// Beispieltyp const patternTypes: Array<Function> = [String, RegExp, Array]
​
// Einige Optionen der Keep-Alive-Komponente verfügbar machen export default {
 Name: 'keep-alive', // Komponentenname abstract: true, // keep-alive ist eine abstrakte Komponente​
 // Drei Props, die bei Verwendung der Keep-Alive-Komponente übergeben werden
 Requisiten: {
 umfassen: Mustertypen,
 ausschließen: Mustertypen,
 max: [Zeichenfolge, Zahl]
 },
​
 erstellt () {
 this.cache = Object.create(null) // Komponenten speichern, die zwischengespeichert werden müssen this.keys = [] // Den Schlüssel jeder Komponente speichern, die zwischengespeichert werden muss, d. h. den Schlüsselwert, der dem this.cache-Objekt entspricht},
​
 // Wenn eine Keep-Alive-Komponente zerstört wird, zerstöre alle Komponenten im Cache destroyd () {
 für (const key in this.cache) {
  pruneCacheEntry(dieser.Cache, Schlüssel, diese.Schlüssel)
 }
 },
​
 // Wenn die Keep-Alive-Komponente gemountet ist, überwacht sie die Änderungen von Include und Exclude und zerstört die zwischengespeicherte Komponente, wenn die Bedingungen erfüllt sind. mounted () {
 dies.$watch('include', val => {
  pruneCache(dieser, Name => Übereinstimmungen(Wert, Name))
 })
 dies.$watch('ausschließen', val => {
  pruneCache(dieser, Name => !matches(Wert, Name))
 })
 },
​
 // Der Punkt ist hier render () {
 const slot = this.$slots.default // Standard-Slot für Keep-Alive-Komponenten const vnode: VNode = getFirstComponentChild(slot) // Erste gültige Komponente des Standard-Slots abrufen // Wenn Vnode vorhanden ist, Optionen von Vnode übernehmen const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
 if (Komponentenoptionen) {
  //Holen Sie sich den Namen der ersten gültigen Komponente
  Konstantname: ?string = getComponentName(Komponentenoptionen)
  const { include, exclude } = this // Einschließen und Ausschließen werden von den Props übergeben
  Wenn (
  // Wenn Include vorhanden ist und Name nicht vorhanden ist oder Name nicht übereinstimmt (include && (!name || !matches(include, name))) ||
  // Wenn Ausschließen vorhanden ist und Name vorhanden ist oder Name übereinstimmt (Ausschließen && Name && Übereinstimmungen(Ausschließen, Name))
  ) {
  return vnode // Gibt an, dass kein Caching erforderlich ist und diese Komponente direkt zum Rendern zurückgegeben wird}
  
  // Wenn eine Übereinstimmung gefunden wird, ist ein Cache-Vorgang erforderlich const { cache, keys } = this // Die Cache-Komponente der Keep-Alive-Komponente und der Schlüssel, der der Cache-Komponente entspricht
  // Den Schlüssel der ersten gültigen Komponente abrufen
  const-Schlüssel: ?string = vnode.key == null
  // Derselbe Konstruktor kann als verschiedene lokale Komponenten registriert werden // Also reicht cid allein nicht aus, verketten wir es? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
  : vnode.schlüssel
  // Wenn diese Komponente den Cache erreicht if (cache[key]) {
  // Diese Komponenteninstanz wird durch die Komponenteninstanz im Cache ersetzt vnode.componentInstance = cache[key].componentInstance
  // Aktualisiere die Position des aktuellen Schlüssels in keysremove(keys, key) // Entferne den aktuellen Schlüssel aus keyskeys.push(key) // Setze ihn ans Ende von keys} else {
  // Wenn der Cache nicht getroffen wird, füge diese Komponente zum Cache hinzu cache[key] = vnode
  keys.push(key) // Setze den Schlüssel dieser Komponente ans Ende von keys // Wenn die Anzahl der Komponenten im Cache das übergebene Maximum überschreitet, zerstöre die LRU-Komponente im Cache if (this.max && keys.length > parseInt(this.max)) {
   pruneCacheEntry(Cache, Schlüssel[0], Schlüssel, this._vnode)
  }
  }
​
  vnode.data.keepAlive = true // Setzt die keepAlive-Eigenschaft dieser Komponente auf true
 }
 // Wenn die erste gültige Komponente existiert, aber ihre Komponentenoptionen nicht existieren, gib diese Komponente zum Rendern zurück // Oder wenn es keine gültige erste Komponente gibt, aber der Standardslot der Keep-Alive-Komponente existiert, gib die erste Komponente des Standardslots zum Rendern zurück return vnode || (Slot && Slot[0])
 }
}

Auffüllen:

Die obige Reihenfolge des Löschens der ersten alten Cache-Komponente und Aktualisierens des Cache-Komponentenschlüssels verwendet tatsächlich die LRU-Cache-Eliminierungsstrategie:
LRU steht für Least Recently Used, was so viel bedeutet wie am wenigsten kürzlich verwendet, und ist ein Speicherverwaltungsalgorithmus.
Dieser Algorithmus basiert auf einer Annahme: Daten, die lange Zeit nicht verwendet wurden, werden in Zukunft wahrscheinlich nicht mehr verwendet. Wenn der von den Daten belegte Speicher einen bestimmten Schwellenwert erreicht, können daher die am wenigsten verwendeten Daten gelöscht werden.

Zusammenfassen

Eine kurze Zusammenfassung lautet:

Wenn die Keep-Alive-Komponente gerendert wird, wird sie gemäß den übergebenen Include- und Exclude-Eigenschaften mit der benannten Komponente übereinstimmen, die in Keep-Alive eingeschlossen ist. Wenn keine Übereinstimmung vorliegt, wird die benannte Komponente direkt zum Rendern zurückgegeben. Wenn eine Übereinstimmung vorliegt, wird ein Cache-Vorgang ausgeführt: Wenn die Komponente bereits im Cache vorhanden ist, wird ihre Instanz ersetzt und die Position des Schlüssels der Komponente in Schlüsseln wird aktualisiert. Wenn die Komponente nicht im Cache vorhanden ist, wird die Komponente im Cache der Keep-Alive-Komponente abgelegt und der Schlüssel der Komponente wird in Schlüsseln abgelegt. Da Include- und Exclude-Eigenschaften beim Mounten überwacht werden, wird bei einer späteren Änderung der Werte dieser beiden Attribute erneut festgestellt, ob die Bedingungen erfüllt sind, und die Komponente wird zerstört.

Damit ist dieser Artikel zur Beantwortung des Caching-Prinzips der Keep-Alive-Komponente aus Sicht des Quellcodes abgeschlossen. Weitere relevante Inhalte zum Caching von Keep-Alive-Komponenten finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Beispielcode für den Keep-Alive-integrierten Komponentencache in Vue
  • Vue Keep-Alive-Beispiel zum dynamischen Löschen des Komponentencaches

<<:  Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.17 winx64

>>:  Windows kann den MySQL-Dienst nicht starten und meldet Fehler 1067 – Lösung

Artikel empfehlen

Unterschied zwischen varchar- und char-Typen in MySQL

Inhaltsverzeichnis vorgenannt VARCHAR-Typ VARCHAR...

HTML+jQuery zur Implementierung einer einfachen Anmeldeseite

Inhaltsverzeichnis Einführung Öffentlicher Code (...

IDEA-Konfigurationsprozess von Docker

IDEA ist das am häufigsten verwendete Entwicklung...

CSS3-Kategoriemenüeffekt

Die CSS3-Kategoriemenüeffekte sind wie folgt: HTM...

Syntax und Beispielanalyse der JavaScript-Array-Methode „reduce()“

Vorwort Die Methode „reduce()“ erhält eine Funkti...

Unterschied zwischen src- und href-Attributen

Es besteht ein Unterschied zwischen src und href ...

Mehrere magische Verwendungen des JS ES6 Spread-Operators

Inhaltsverzeichnis 1. Attribute hinzufügen 2. Meh...

JavaScript zum Erzielen eines einfachen Drag-Effekts

In diesem Artikel wird der spezifische JavaScript...

Warum sollte CSS im Head-Tag platziert werden?

Denken Sie darüber nach: Warum sollte css im head...

Mehrere spezifische Methoden zur MySQL-Speicherplatzbereinigung

Inhaltsverzeichnis Vorwort 1. Überprüfen Sie die ...

Tabellen dynamisch in HTML hinzufügen_PowerNode Java Academy

Ohne weitere Umschweife werde ich den Code direkt...