Detaillierte Erklärung des Sandbox-Mechanismus von Vue3

Detaillierte Erklärung des Sandbox-Mechanismus von Vue3

Vorwort

Es gibt zwei Haupttypen von Vue3-Sandboxen

  1. Die browserkompilierte Version verwendet die with-Syntax plus Proxy-Interception
  2. Die lokal vorkompilierte Version verwendet das Plugin „transformExpression“, um den Nicht-Whitelist-Bezeichner während der Vorkompilierungsphase der Vorlage unter das Proxy-Objekt der Komponente zu hängen.

Browser kompilierte Version

Ergebnis der Renderfunktionskompilierung

<div>{{test}}</div>
<div>{{Math.floor(1)}}</div>

Zu

_Vue = Vue;

Rückgabefunktion rendern(_ctx, _cache, $props, $setup, $data, $options) {
  mit (_ctx) {
    Konstante {
      toDisplayString: _toDisplayString,
      VNode erstellen: _createVNode,
      Fragment: _Fragment,
      offenerBlock: _openBlock,
      Block erstellen: _createBlock,
    } = _Vue;

    zurückkehren (
      _openBlock(),
      _Block erstellen(
        _Fragment,
        null,
        [
          _createVNode("div", null, _toDisplayString(test), 1 /* TEXT */),
          _createVNode(
            "div",
            null,
            _toDisplayString(Math.floor(1)),
            1 /* TEXT */
          ),
        ],
        64 /* STABILES_FRAGMENT */
      )
    );
  }
};

Aus dem obigen Code können wir erkennen, dass der Variablenkennung kein Präfix hinzugefügt wurde, sondern sie nur mit der Syntax „with“ umschlossen ist, um die Gültigkeitskette zu erweitern. Wie wird also die JS-Sandbox-Interception erreicht? Beispielsweise die Variable test. Theoretisch gibt es in der aktuellen Bereichskette keine Testvariable. Die Variable wird vom vorherigen Bereich aus durchsucht, bis der globale Bereich gefunden wird. In der Praxis wird jedoch nur nach _ctx gesucht. Das Prinzip ist sehr einfach. _ctx ist ein Proxy-Objekt. Wie verwenden wir also Proxy zum Abfangen? Der Beispielcode lautet wie folgt:

const GLOBALS_WHITE_LISTED =
  "Unendlich, undefiniert, NaN, ist endlich, ist NaN, parseFloat, parseInt, decodeURI," +
  "URI-Komponente dekodieren,URI kodieren,URI-Komponente kodieren,Mathematik,Zahl,Datum,Array," +
  "Objekt, Boolescher Wert, Zeichenfolge, Regulärer Ausdruck, Karte, Satz, JSON, Intl, BigInt";

const isGloballyWhitelisted = (Schlüssel) => {
  gibt GLOBALS_WHITE_LISTED.split(",").includes(Schlüssel); zurück
};

const hasOwn = (Objekt, Schlüssel) => {
  gibt Object.prototype.hasOwnProperty.call(Objekt, Schlüssel) zurück;
};

const Herkunft = {};
const _ctx = neuer Proxy (Ursprung, {
  get(Ziel, Schlüssel, Empfänger) {
    wenn (hasOwn(Ziel, Schlüssel)) {
      Reflect.get(Ziel, Schlüssel, Empfänger);
    } anders {
      konsole.warnen(
        `Auf die Eigenschaft ${JSON.stringify(key)} wurde während des Renderns zugegriffen ` +
          `ist aber in der Instanz nicht definiert.`
      );
    }
  },
  hat(Ziel, Schlüssel) {
    // Wenn es ein globales Objekt ist, gib „false“ zurück, löse kein „Get Interception“ aus und suche nach Variablen aus dem vorherigen Bereich. // Wenn es kein globales Objekt ist, gib „true“ zurück und löse „Get Interception“ aus. return !isGloballyWhitelisted(key);
  },
});

Der Code ist sehr einfach. Warum kann ein so einfacher Code ein Abfangen erreichen? Da die with-Anweisung die has-Abfangfunktion auslöst, wird, wenn has true zurückgibt, die get-Abfangfunktion des Proxy-Objekts ausgelöst. Wenn false zurückgegeben wird, wird die get-Abfangfunktion des Proxy-Objekts nicht ausgelöst und die Variable wird nicht im aktuellen Proxy-Objekt gesucht, sondern direkt im oberen Bereich.

Lokale vorkompilierte Version

<div>{{test}}</div>
<div>{{Math.floor(1)}}</div>

Zu

importieren {
  toDisplayString als _toDisplayString,
  createVNode als _createVNode,
  Fragment als _Fragment,
  openBlock als _openBlock,
  Block erstellen als _createBlock,
} von "vue";

Exportfunktion rendern(_ctx, _cache, $props, $setup, $data, $options) {
  zurückkehren (
    _openBlock(),
    _Block erstellen(
      _Fragment,
      null,
      [
        _createVNode("div", null, _toDisplayString(_ctx.a), 1 /* TEXT */),
        _createVNode(
          "div",
          null,
          _toDisplayString(Math.floor(1)),
          1 /* TEXT */
        ),
      ],
      64 /* STABILES_FRAGMENT */
    )
  );
}

Aus dem obigen Code können wir ersehen, dass den Nicht-Whitelist-Bezeichnern die Variable _ctx vorangestellt ist. Wie wird das also gemacht? Beim lokalen Kompilieren der Vorlage wird während der Konvertierungsphase der variable Ausdrucksknoten NodeTypes.SIMPLE_EXPRESSION vorangestellt. Der Beispielcode lautet wie folgt:

const GLOBALS_WHITE_LISTED =
  "Unendlich, undefiniert, NaN, ist endlich, ist NaN, parseFloat, parseInt, decodeURI," +
  "URI-Komponente dekodieren,URI kodieren,URI-Komponente kodieren,Mathematik,Zahl,Datum,Array," +
  "Objekt, Boolescher Wert, Zeichenfolge, Regulärer Ausdruck, Karte, Satz, JSON, Intl, BigInt";

const isGloballyWhitelisted = (Schlüssel) => {
  gibt GLOBALS_WHITE_LISTED.split(",").includes(Schlüssel); zurück
};
const isLiteralWhitelisted = (Schlüssel)=>{
  returniere 'true, false, null, this'.split(',').includes(Schlüssel)
}
Exportfunktion processExpression(
  Knoten
) {
  const rewriteIdentifier = (roh) => {
    gibt `_ctx.${raw}` zurück
  }
  const rawExp = node.inhalt
  wenn (istSimpleIdentifier(rawExp)) {
    const isAllowedGlobal = isGloballyWhitelisted(rawExp)
    const isLiteral = isLiteralWhitelisted(rawExp)
    wenn (!istAllowedGlobal && !istLiteral) {
      node.content = rewriteIdentifier(Rohdatenausdruck)
    }
    Rückgabeknoten
  }

Natürlich ist der obige Code nur eine vereinfachte Version. Das ursprüngliche Plugin präzisiert auch __props $setup, verkürzt den variablen Abfragepfad, verbessert die Leistung und kompiliert komplexe Ausdrücke wie Pfeilfunktionen über Babel.

Zusammenfassen

Der gesamte Sandbox-Mechanismus von vue3 js wird erklärt. Die browserkompilierte Version hat mich lange gestört, weil ich nicht wusste, dass sie Abfragen mit Anweisungsvariablen abfangen kann.

Oben finden Sie eine ausführliche Erläuterung des Sandbox-Mechanismus von vue3. Weitere Informationen zum Sandbox-Mechanismus von vue3 finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Springboot + Vue + Docking-Alipay-Schnittstelle + Zahlungsfunktion zum Scannen von QR-Codes (Sandbox-Umgebung)
  • Vue referenziert auf mehrere Arten von JS-Dateien (empfohlen)
  • Detaillierte Erläuterung der vier Möglichkeiten des Vue-Routing-Sprungs (mit Parametern)
  • Beispiel für die Kommunikation zwischen übergeordneten und untergeordneten Komponenten von Vue (props, $ref, $emit)
  • Detaillierte Erklärung zur Verwendung von Vue-Props (Zusammenfassung)
  • Drei Möglichkeiten zum Aktualisieren der aktuellen Seite im Vue-Projekt
  • Einfaches Verständnis von Props-Attributen in Vue
  • Ausblenden und Anzeigen von VUE-Elementen (v-show-Direktive)
  • Vue implementiert Datei-Upload-Funktion
  • Drei Möglichkeiten zum Hochladen von Bildern mit Vue
  • Zusammenfassung gängiger Vue.js-Anweisungen (v-if, v-for usw.)

<<:  Die Magie des tr-Befehls beim Zählen der Häufigkeit englischer Wörter

>>:  Detaillierte Erläuterung möglicher Probleme bei der Konvertierung von Gleitkommadaten in Zeichendaten in MySQL

Artikel empfehlen

Eine kurze Erläuterung des Sperrbereichs der MySQL-Next-Key-Sperre

Vorwort Eines Tages wurde ich plötzlich nach der ...

HTML+CSS zum Erreichen eines reaktionsfähigen Karten-Hover-Effekts

Inhaltsverzeichnis erreichen: Zusammenfassen: Daz...

So erstellen Sie einen MySQL PXC-Cluster

Inhaltsverzeichnis 1. Einführung in PXC 1.1 Einfü...

Fehlereinfügungsanalyse der Funktion „updatexml()“ von MySQL

Verstehen Sie zunächst die Funktion updatexml() U...

Teilen Sie 5 hilfreiche CSS-Selektoren, um Ihr CSS-Erlebnis zu bereichern

Dank unserer umfassenden CSS-Erfahrung als Webdesi...

Implementierung der Vorschaufunktion mehrerer Bild-Uploads auf HTML-Basis

Ich habe vor kurzem ein Skript zum Hochladen mehr...

Lernen Sie die Grundlagen von nginx

Inhaltsverzeichnis 1. Was ist nginx? 2. Was kann ...

Detaillierte Erläuterung der Systemeingabe- und -ausgabeverwaltung in Linux

Verwaltung der Ein- und Ausgaben im System 1. Ver...

Grundlegende Schritte zur Verwendung einer Mysql-SSH-Tunnelverbindung

Vorwort Aus Sicherheitsgründen kann sich der Root...

Vue implementiert Drag & Drop oder Klicken zum Hochladen von Bildern

In diesem Artikel wird der spezifische Code von V...

Vue3 AST Parser-Quellcode-Analyse

Inhaltsverzeichnis 1. Generieren Sie einen abstra...