Details zur Vue-Vorlagenkompilierung

Details zur Vue-Vorlagenkompilierung

denken:

HTML ist eine Tag-Sprache und nur JS kann Urteile und Schleifen implementieren. Vorlagen enthalten Anweisungen, Interpolationen und JS-Ausdrücke, die Urteile, Schleifen usw. implementieren können. Daher sind Vorlagen kein HTML und müssen daher in eine Art JS-Code konvertiert werden. Wie wird diese Kompilierung durchgeführt?

Analyse:

Unter Vorlagenkompilierung versteht man den Prozess, bei dem eine Vorlage in eine Renderfunktion kompiliert wird. Dieser Prozess kann grob in drei Phasen unterteilt werden:

1. analysieren

Der Parser konvertiert hauptsächlich Template-Strings in element ASTs

Vorlagenzeichenfolgen:

<div>
   <p>{{Nachricht}}</p>
</div>

Element-ASTs

AST bezieht sich auf den abstrakten Syntaxbaum und ähnelt Vnode . Beide verwenden JavaScript Objekte, um die Baumdarstellung von Knoten zu beschreiben.

{
  tag: "div"
  // Knotentyp (1 Bezeichnung, 2 Textknoten mit wörtlichem Ausdruck, 3 normaler Textknoten oder Kommentarknoten)
  Typ: 1,
  // statischer Stammknoten staticRoot: false,
  // Statischer Knoten static: false,
  schlicht: wahr,
  // Verweis auf das übergeordnete Knotenelement Beschreibungsobjekt parent: undefiniert,
  // Nur wenn der Knotentyp 1 ist, gibt es ein attrsList-Attribut, bei dem es sich um ein Objektarray handelt, das den ursprünglichen HTML-Attributnamen und -wert attrsList speichert: [],
  // Wie oben, der Unterschied besteht darin, dass attrsMap den HTML-Attributnamen und -Wert in Schlüssel-Wert-Paaren speichert: attrsMap: {},
  //Speichert das Elementbeschreibungsobjekt aller untergeordneten Knoten dieses Knotens children: [
      {
      Schlagwort: "p"
      Typ: 1,
      staticRoot: false,
      statisch: falsch,
      schlicht: wahr,
      übergeordnet: {tag: "div", ...},
      attrsList: [],
      attrsMap: {},
      Kinder: [{
          Typ: 2,
          text: "{{message}}",
          statisch: falsch,
          // Wenn der Knotentyp 2 ist, enthält das Objekt den Ausdruck expression: "_s(message)"
      }]
    }
  ]
}

1.1 Regeln für das Abfangen

Hauptsächlich durch Beurteilen des Werts von html.indexof('<') in der Vorlage, um zu bestimmen, ob das Tag oder der Text abgefangen werden soll.

Der Abfangvorgang:

Streicherteil

`<div><p>{{Nachricht}}<p></div>`

1.2 Teil des Abfangprozesses

Erste Interception

  • Bestimmen Sie den Wert von html.indexof('<') in der Vorlage, der Null ist (einer von Kommentar, bedingtem Kommentar, doctype , Start-Tag, End-Tag).
  • Der reguläre Ausdruck des Start-Tags wird erfolgreich abgeglichen, der aktuelle Tag-Name wird als div abgerufen und anschließend wird der übereinstimmende Teil „<div“ abgeschnitten, um die neue Zeichenfolge ><p>{{message}}</p></div> zu erhalten.
  • Nach dem Abschneiden des Start-Tags wird der reguläre Ausdruck des passenden Attributs zum Abgleichen verwendet. Wenn der Abgleich erfolgreich ist, wird die Attributliste des Tags abgerufen. Wenn der Abgleich nicht erfolgreich ist, ist die Attributliste des Tags ein leeres Array.
  • Nachdem die Attribute abgeschnitten wurden, wird der reguläre Ausdruck, der mit dem Ende des Start-Tags übereinstimmt, verwendet, um Informationen darüber zu erhalten, ob es sich um ein selbstschließendes Tag handelt, und dann wird die übereinstimmende Zeichenfolge abgeschnitten, um eine neue Zeichenfolge zu erhalten <p>{{message}}</p></div>
  • Passen Sie das Start-Tag an und bestimmen Sie, ob der aktuelle Knoten einen Stammknoten hat. Wenn nicht, wird ein Baumknoten des Elementtyps erstellt. Wenn er vorhanden ist, wird er als untergeordneter Knoten von currentParent festgelegt und der aktuelle Knoten wird in den stack verschoben.
/**
   Zusammenfassend lässt sich sagen: Tags abgleichen, Attribute extrahieren und Hierarchien erstellen*/
// Nach dem obigen Abgleich ist die verbleibende Zeichenfolge:
`<p>{{Nachricht}}<p></div>`

Zweite Interception

/**
    Wie oben*/
// Nach dem obigen Abgleich ist die verbleibende Zeichenfolge:
`{{Nachricht}}</p></div>`

Das dritte Abfangen

  • Bestimmen Sie den Wert von html.indexof('<') in der Vorlage, der größer oder gleich Null ist (einer von Text und Ausdruck).
  • Fragen Sie das nächste '<' ab und vergleichen Sie es, um zu sehen, ob es übereinstimmt (eines der Start-Tags, End-Tags, Kommentare, bedingten Kommentare). Wenn die Übereinstimmung erfolgreich ist, endet die Durchquerung. Wenn nicht, wird die Durchquerung fortgesetzt.

Zum Beispiel:

a < b </p> => Textteil a < b , trifft das End-Tag

a<b</p> => Textteil a
, drücken Sie das Start-Tag <b

/**
   Zusammenfassend lässt sich sagen, dass der Typ bestimmt und der Text abgefangen werden muss*/
// Nach dem obigen Abgleich ist die verbleibende Zeichenfolge:
`</p></div>`


Vierte Interception

  • Bestimmen Sie den Wert von html.indexof('<') in der Vorlage, der Null ist (einer von Kommentar, bedingtem Kommentar, Doctype, Start-Tag, End-Tag).
  • Der reguläre Ausdruck des Endtags wird erfolgreich abgeglichen, und dann wird der übereinstimmende Teil </p> abgeschnitten, um die neue Zeichenfolge zu erhalten </div>
  • Wenn das End-Tag übereinstimmt, wird ein Knoten „p“ aus dem Stapel entfernt und der letzte Knoten „div“ im Stapel als currentParent
/**
    Zusammenfassend lässt sich sagen: Ordnen Sie das Etikett zu und bestimmen Sie die Ebene*/
// Nach dem obigen Abgleich ist die verbleibende Zeichenfolge:
`</div>`
Die fünfte Interception/**
    Wie oben*/
Beenden

1.3 Parser-Zusammenfassung

  • Der Prozess der Konvertierung von Vorlagenzeichenfolgen in element ASTs ist eigentlich der Prozess des kontinuierlichen Abfangens und Analysierens von Zeichenfolgen.
  • Wenn das Start-Tag übereinstimmt, wird das entsprechende Start-Tag abgefangen, die Grundstruktur von AST definiert, die Attribute ( attrs , tagName ), Anweisungen usw. des Tags analysiert und das Tag in den Stapel geschoben.
  • Wenn das End-Tag übereinstimmt, muss tagName jedes Elements im Stapel von hinten nach vorne durch tagName dieses End-Tags abgeglichen werden, und alle Elemente nach dem übereinstimmenden Element werden gelöscht (aus dem Stapel entfernt). Daher ist das letzte Element im Stapel das übergeordnete Element.
  • Während der Analysephase werden die Knoten abgeflacht und haben keine hierarchische Beziehung. Durch Beobachten des Knotenbaums können wir feststellen, dass der innerste Knoten analysiert wird und der letzte zu analysierende Knoten häufig das übergeordnete Element ist. Daher verwenden wir einen Stapel, um die hierarchische Beziehung der Knoten aufzuzeichnen.
  • Das selbstschließende Tag <input /> hat keine untergeordneten Knoten und muss daher nicht auf den stack push .

2. Optimieren

Die Hauptfunktion des Optimierers besteht darin, den statischen Inhalt des generierten AST zu optimieren und statische Knoten zu markieren. Um jedes Mal erneut zu rendern, müssen keine neuen Knoten für den statischen Teilbaum erstellt werden, und patch Prozess im virtuellen DOM kann übersprungen werden (dh es ist keine Teilnahme am Rendern der zweiten Seite erforderlich, was die Rendereffizienz erheblich verbessert).

2.1 Statische Knoten

Durchlaufen Sie den AST-Syntaxbaum, finden Sie alle statischen Knoten und markieren Sie sie

Funktion ist statisch (Knoten) {
    // Ausdruck
    wenn (Knotentyp === 2) {
      return false
    }
    //Text
    wenn (Knotentyp === 3) {
      returniere wahr
    }
    /**
 

1. Die dynamische Bindungssyntax kann nicht verwendet werden, d. h. das Tag darf keine Attribute haben, die mit v-, @ oder :; beginnen.
2. Sie können keine v-if-, v-else- und v-for-Anweisungen verwenden.
3. Es darf sich nicht um eine integrierte Komponente handeln, d. h. der Tag-Name darf nicht slot und component sein.
4. Der Tag-Name muss ein für die Plattform reserviertes Tag sein, d. h. er darf keine Komponente sein.
5. Der übergeordnete Knoten des aktuellen Knotens kann kein template mit v-for sein;
6. Die Schlüssel aller Attribute des Knotens müssen Schlüssel sein, die nur in statischen Knoten vorhanden sind. Hinweis: Die Schlüssel statischer Knoten sind begrenzt.

Es kann nur einer der type sein: Tag, attrsList, attrsMap, plain, parent, children, attrs;

    */
    zurück !!(node.pre || (
      !node.hasBindings &&
      !Knoten.wenn && !Knoten.für &&
      !isBuiltInTag(node.tag) &&
      isPlatformReservedTag(node.tag) &&
      !isDirectChildOfTemplateFor(Knoten) &&
      Objekt.Schlüssel(Knoten).Jeder(istStatischerSchlüssel)
    ))
}

2.2 Statischer Stammknoten

Durchlaufen Sie den Baum nach den obigen Schritten, finden Sie den statischen Stammknoten und markieren Sie ihn

2.3 Optimierer-Zusammenfassung

  • Knoten, die nicht die einzigartige Syntax von Vue verwenden (außer v-pre v-once ), können als statische Knoten bezeichnet werden.
  • Statischer Knoten: bezieht sich auf den aktuellen Knoten und alle seine untergeordneten Knoten sind statische Knoten
  • Statischer Stammknoten: Bezieht sich auf einen Knoten, der selbst und alle seine untergeordneten Knoten statische Knoten sind, der übergeordnete Knoten jedoch ein dynamischer Knoten ist.

3. Codegenerator generieren

Die Funktion des Codegenerators besteht darin, über den AST-Syntaxbaum eine Codezeichenfolge zu generieren. Die Codezeichenfolge wird in die Rendering-Funktion gepackt. Nachdem die Rendering-Funktion ausgeführt wurde, kann ein Vnode abgerufen werden.

3.1 JS mit Syntax

Die Verwendung von with kann die Art und Weise ändern, wie nach freien Variablen in {} gesucht wird, und nach freien Variablen in {} als Attribute von obj suchen. Wenn kein passendes obj-Attribut gefunden wird, wird ein Fehler gemeldet.

const obj = {a: 100, b: 200}
mit(Objekt) {
     konsole.log(a)
     console.log(b)
     // console.log(c) // meldet einen Fehler}

Codezeichenfolge

Analysieren Sie die von Parse generierten Element-ASTs und verketten Sie sie zu Zeichenfolgen.

mit(diesem){return _c('div',_c('p',[_v(Nachricht)])])}

Holen Sie sich die Renderfunktion:

/** Der Codestring kann die Renderfunktion der aktuellen Komponente über die neue Funktion ('Codestring') abrufen*/

const stringCode = `mit(diesem){return _c('div',_c('p',[_v(Nachricht)])])}`

const render = neue Funktion (StringCode).

Um verschiedene Anweisungen, Interpolationen und JS-Ausdrücke anzuzeigen, können Sie vue-template -Konvertierung verwenden

const-Compiler = erforderlich('vue-template-compiler')
// Interpolation const template = `<p>{{message}}</p>`
const Ergebnis = Compiler.Compile(Vorlage)
Konsole.log(Ergebnis.Rendern)
// mit(diesem){return _c('p',[_v(_s(Nachricht))])}


Vue-Quellcode, um die Bedeutung der Abkürzungsfunktion zu finden

Der Quellcode zur Kompilierung der Vorlage befindet sich im Paket `vue-template-compiler` [2]

Funktion installRenderHelpers(Ziel) {
    target._c = Element erstellen
    // Tag v-once
    ziel._o = Einmal markieren
    // In Zahlentyp konvertieren target._n = toNumber
    // In Zeichenfolge konvertieren target._s = toString
    // Rendern Sie v-for
    ziel._l = Renderliste
    // Rendere normale Slots und Slots mit eingeschränktem Gültigkeitsbereich target._t = renderSlot
    // Rendere statische Knoten durch staticRenderFns target._m = renderStatic
    // Holen Sie sich das Filterziel._f = resolveFilter
    //Überprüfe den Tastencode des Tastaturereignisses
    target._k = Schlüsselcodes prüfen
    target._b = bindObjectProps
    // Einen Text-Vnode erstellen
    target._v = TextVNode erstellen
    // Einen leeren Vnode erstellen
    target._e = erstelleEmptyVNode
    target._u = auflösenScopedSlots
    target._g = bindObjectListeners
    //Verarbeitung des Modifikators target._p = prependModifier
}

Zusammenfassung:

Beim Vue-Scaffolding wird vue-loader zum Kompilieren von Vorlagen in der Entwicklungsumgebung verwendet (Vorkompilierung).

Der Analyseprozess besteht darin, die Zeichenfolge in kleinen Segmenten abzufangen und dann einen Stapel beizubehalten, um die DOM-Tiefe zu speichern. Wenn alle Zeichenfolgen abgefangen wurden, wird ein vollständiger AST analysiert.

Der Optimierungsprozess besteht darin, alle Knoten rekursiv zu markieren, um anzuzeigen, ob es sich um statische Knoten handelt, und dann die statischen Stammknoten erneut rekursiv zu markieren.

In der Codegenerierungsphase wird rekursiv eine Zeichenfolge mit Funktionsausführungscode generiert. Der rekursive Prozess ruft je nach Knotentyp unterschiedliche Generierungsmethoden auf.

Dies ist das Ende dieses Artikels über die Einzelheiten der Vue-Vorlagenkompilierung. Weitere relevante Inhalte zur Vue-Vorlagenkompilierung finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Analyse des Idea-Compiler-Vue-Einrückungsfehlerproblemszenarios
  • So verwenden Sie den Rich-Text-Editor wangEditor3 in Vue
  • Vue3-Kompilierungsprozess - Quellcodeanalyse
  • Vertieftes Verständnis des Prinzips der Vue3-Vorlagenkompilierung
  • Lösen Sie das Problem, dass Vue-cli es6 nicht kompilieren kann
  • Lösung zur Optimierung der Vue-Projektverpackung und -Kompilierung
  • Eine kurze Diskussion über die Code-Erkundung, die durch die Kompilierung von Vue-Projekten durch Webpack generiert wird

<<:  Implementierung einer geplanten Sicherung in Mysql5.7

>>:  Implementierung der Docker Compose-Mehrcontainerbereitstellung

Artikel empfehlen

So verbessern Sie die MySQL Limit-Abfrageleistung

Bei MySQL-Datenbankoperationen hoffen wir immer, ...

Anwendungsverschachtelung von HTML-ul-ungeordneten Tabellen

Anwendungsschachtelung ungeordneter Listen Code ko...

Implementierungscode zur Installation von vsftpd in Ubuntu 18.04

Installieren Sie vsftpd $ sudo apt-get installier...

Neue Features in MySQL 8: Unsichtbare Indizes

Hintergrund Indizes sind ein zweischneidiges Schw...

CSS-Randüberlappungen und wie man sie verhindert

Die vertikal benachbarten Kanten zweier oder mehr...

Zusammenfassung des Wissens zu MySQL-Sperren

Sperren in MySQL Sperren sind ein Mittel, um Ress...

Umfassendes Verständnis des MySQL-Protokolls für langsame Abfragen

Inhaltsverzeichnis Was ist das Protokoll langsame...

Welche Vorteile bietet die Verwendung von B+Tree als Index in MySQL?

Inhaltsverzeichnis Warum benötigen Datenbanken In...

Layout im Vue.js-Stil Allgemeine Fähigkeiten zur Flutter-Geschäftsentwicklung

Korrespondenz zwischen Flutter und CSS im Shadow-...

Der Unterschied zwischen HTML-Name-ID und Klasse_PowerNode Java Academy

Name Geben Sie einen Namen für das Tag an. Format...

Ein kurzes Verständnis der drei Prinzipien zum Hinzufügen von MySQL-Indizes

1. Die Bedeutung von Indizes Indizes werden verwe...

Lösung für das Problem, dass der Z-Index in CSS3 nicht wirksam wird

Ich habe vor kurzem eine Kombination aus CSS3 und...