SzeneneinführungBeim Arbeiten an H5 bin ich kürzlich auf ein Szenario gestoßen: Jede Seite muss eine Kopfzeile mit einem Titel anzeigen. Eine Implementierungsidee ist die Verwendung globaler Komponenten. Angenommen, wir erstellen eine globale Komponente namens TheHeader.vue. Der Pseudocode lautet wie folgt: <Vorlage> <h2>{{ Titel }}</h2> </Vorlage> <Skript> Standard exportieren { Requisiten: { Titel: Typ: Zeichenfolge, Standard: '' } } } </Skript> Nachdem Sie die globale Komponente erstellt haben, verweisen Sie in jeder Seitenkomponente darauf und übergeben Sie sie an Props. Wenn wir beispielsweise auf diese Komponente auf Seite A verweisen, ist die Komponente, die Seite A entspricht, A.vue <Vorlage> <div> <TheHeader :title="Titel" /> </div> </Vorlage> <Skript> Standard exportieren { Daten() { Titel: '' }, erstellt(){ this.title = 'Meine Homepage' } } </Skript> Die Verwendung ist sehr einfach, es gibt jedoch einen Nachteil: Wenn die Header-Komponente viele Requisiten übergeben muss, ist es mühsam, die entsprechenden Requisiten in der Seitenkomponente beizubehalten. In diesem Fall gibt es eine bessere Idee zur Implementierung dieses Szenarios, nämlich die Verwendung des Vue-Plug-Ins. Die gleiche Methode zum Aufrufen der Kopfkomponente in der A.vue-Komponente ist bei Verwendung des Vue-Plugins prägnanter: <Vorlage> <div /> </Vorlage> <Skript> Standard exportieren { erstellt(){ this.$setHeader('Meine Homepage') } } </Skript> Wir können sehen, dass bei Verwendung des Vue-Plugins zur Implementierung die TheHeader-Komponente nicht explizit in A.vue eingefügt werden muss und auch die entsprechenden Props nicht in die Datenfunktion von A.vue eingefügt werden müssen. Sie müssen nur eine Funktion aufrufen. Also, wie funktioniert dieses Plugin? Plugin-ImplementierungDie konkreten Schritte zur Umsetzung sind wie folgt:
Lassen Sie uns anhand der obigen Schritte eine Datei plugin.js erstellen: importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren const headerPlugin = { installieren(Vue) { const vueInstance = neu (Vue.extend(TheHeader))().$mount() Vue.prototype.$setHeader = Funktion(Titel) { vueInstance.title = Titel Dokument.body.prepend(vueInstance.$el) } } } Vue.use(headerPlugin) Anschließend führen wir plugin.js in main.js ein, um den gesamten logischen Prozess der Plugin-Implementierung abzuschließen. Obwohl dieses Plugin implementiert wurde, gibt es jedoch einige Probleme. Problem 1: Doppelte Header-KomponentenWenn wir es in einer Einzelseitenkomponente verwenden, werden wir, solange wir die Methode router.push verwenden, auf ein magisches Problem stoßen: Auf der neuen Seite werden zwei Header-Komponenten angezeigt. Wenn wir noch ein paar Mal springen, erhöht sich auch die Anzahl der Kopfkomponenten. Dies liegt daran, dass wir diese Methode auf jeder Seite aufrufen, sodass jede Seite das entsprechende DOM in das Dokument einfügt. Unter Berücksichtigung dessen müssen wir die oben genannten Komponenten optimieren. Wir platzieren den Instanziierungsprozess außerhalb des Plugins: importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren const vueInstance = neu (Vue.extend(TheHeader))().$mount() const headerPlugin = { installieren(Vue) { Vue.prototype.$setHeader = Funktion(Titel) { vueInstance.title = Titel Dokument.body.prepend(vueInstance.$el) } } } Vue.use(headerPlugin) Bei diesem Vorgang wird das DOM immer noch wiederholt in das Dokument eingefügt. Da es sich jedoch um dieselbe Vue-Instanz handelt, hat sich der entsprechende DOM nicht geändert, sodass immer nur ein eingefügtes DOM vorhanden ist. Auf diese Weise haben wir das Problem der Anzeige mehrerer Header-Komponenten gelöst. Um den Vorgang des Einfügens in das DOM nicht wiederholen zu müssen, können wir auch eine Optimierung vornehmen: importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren const vueInstance = neu (Vue.extend(TheHeader))().$mount() const hasPrepend = false const headerPlugin = { installieren(Vue) { Vue.prototype.$setHeader = Funktion(Titel) { vueInstance.title = Titel wenn (!hasPrepend) { Dokument.body.prepend(vueInstance.$el) hasPrepend = true } } } } Vue.use(headerPlugin) Fügen Sie eine Variable hinzu, um zu steuern, ob das DOM eingefügt wurde. Wenn es eingefügt wurde, wird der Einfügevorgang nicht ausgeführt. Nach der Optimierung ist die Implementierung dieses Plugins fast abgeschlossen. Allerdings bin ich während der Implementierung auf mehrere Probleme gestoßen, die ich hier aufzeichnen werde. Frage 2: Eine andere ImplementierungsideeWährend des Implementierungsprozesses kam mir plötzlich eine Idee: Kann ich die Datenfunktion der TheHeader-Komponente direkt ändern, um diese Komponente zu implementieren? Sehen Sie sich den folgenden Code an: importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren let el = null const headerPlugin = { installieren(Vue) { Vue.prototype.$setHeader = Funktion(Titel) { TheHeader.data = function() { Titel } const vueInstance = neu (Vue.extend(TheHeader))().$mount() el = vueInstance.$el wenn (el) { Dokument.Body.RemoveChild(el) Dokument.Body.prepend(el) } } } } Vue.use(headerPlugin) Es sieht nicht so aus, als ob damit irgendetwas nicht stimmt. Nach einiger Übung stellte sich jedoch heraus, dass beim Aufruf der Methode $setHeader nur der erste übergebene Wert wirksam wird. Wenn beispielsweise die erste Eingabe „Meine Homepage“ und die zweite Eingabe „Persönliche Daten“ lautet, wird in der Header-Komponente immer „Meine Homepage“ und nicht „Persönliche Daten“ angezeigt. Was ist der Grund? Nach eingehender Untersuchung des Vue-Quellcodes stellte sich heraus, dass Header nach dem ersten Aufruf von new Vue eine zusätzliche Ctor-Eigenschaft hatte, die den der Header-Komponente entsprechenden Konstruktor zwischenspeicherte. Beim nachfolgenden Aufruf von new Vue(TheHeader) wird immer der erste Cache als Konstruktor verwendet, der Wert des Titels ändert sich also nicht. Der dem Vue-Quellcode entsprechende Code lautet wie folgt: Vue.extend = Funktion (Erweiterungsoptionen) { erweiternOptionen = erweiternOptionen || {}; var Super = dies; var SuperId = Super.cid; var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {}); if (cachedCtors[SuperId]) { // Wenn ein Cache vorhanden ist, gib den zwischengespeicherten Konstruktor direkt zurück return cachedCtors[SuperId] } var name = extendOptions.name || Super.options.name; wenn (Prozess.env.NODE_ENV !== 'Produktion' && Name) { validiereKomponentenname(Name); } var Sub = Funktion VueComponent (Optionen) { this._init(Optionen); }; Sub.prototype = Objekt.erstellen(Super.prototype); Sub.prototype.constructor = Sub; Sub.cid = cid++; Untergeordnete Optionen = MergeOptions( Super.options, Erweiterungsoptionen ); Sub['super'] = Super; // Für Props und berechnete Eigenschaften definieren wir die Proxy-Getter auf // die Vue-Instanzen zur Erweiterungszeit, auf dem erweiterten Prototyp. Dies // vermeidet Object.defineProperty-Aufrufe für jede erstellte Instanz. wenn (Sub.options.props) { : InitProps$1(Sub); } wenn (Sub.options.computed) { initComputed$1(Sub); } // weitere Nutzung von Erweiterungen/Mixins/Plugins zulassen Sub.extend = Super.extend; Sub.mixin = Super.mixin; Sub.use = Super.use; // Asset-Register erstellen, also erweiterte Klassen // können auch über ihr Privatvermögen verfügen. ASSET_TYPES.forEach(Funktion (Typ) { Sub[Typ] = Super[Typ]; }); // rekursive Selbstsuche aktivieren wenn (Name) { Sub.Optionen.Komponenten[Name] = Sub; } // Behalten Sie zum Zeitpunkt der Erweiterung einen Verweis auf die Superoptionen bei. // später bei der Instanziierung können wir prüfen, ob die Optionen von Super // wurde aktualisiert. Sub.superOptions = Super.options; Sub.extendOptions = Erweiterungsoptionen; Sub.sealedOptions = erweitern({}, Sub.options); // Cache-Konstruktor cachedCtors[SuperId] = Sub; // Hier wird der Ctor-Konstruktor zwischengespeichert return Sub } Nachdem wir den Grund gefunden haben, werden wir feststellen, dass diese Methode auch möglich ist. Wir müssen nur eine Codezeile in plugin.js hinzufügen importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren let el = null const headerPlugin = { installieren(Vue) { Vue.prototype.$setHeader = Funktion(Titel) { TheHeader.data = function() { Titel } DerHeader.Ctor = {} const vueInstance = new Vue(DerHeader).$mount() el = vueInstance.$el wenn (el) { Dokument.Body.RemoveChild(el) Dokument.Body.prepend(el) } } } } Vue.use(headerPlugin) Jedes Mal, wenn wir die Methode $setHeader ausführen, entfernen wir einfach den zwischengespeicherten Konstruktor. Frage 3: Ist es möglich, Vue.extend nicht zu verwenden?Tatsächlich ist es möglich, Vue direkt zu verwenden, ohne Vue.extend zu verwenden. Der entsprechende Code lautet wie folgt: importiere TheHeader aus './TheHeader.vue' Vue von „vue“ importieren const vueInstance = new Vue(DerHeader).$mount() const hasPrepend = false const headerPlugin = { installieren(Vue) { Vue.prototype.$setHeader = Funktion(Titel) { vueInstance.title = Titel wenn (!hasPrepend) { Dokument.body.prepend(vueInstance.$el) hasPrepend = true } } } } Vue.use(headerPlugin) Die direkte Verwendung von Vue zum Erstellen einer Instanz ist besser als die Verwendung von Extend zum Erstellen einer Instanz, da dabei die Ctor-Eigenschaft in Header.vue nicht zwischengespeichert wird. Aber ich habe schon einmal gesehen, wie Vant die Toast-Komponente implementiert hat, die im Grunde die Vue.extend-Methode verwendet, anstatt Vue direkt zu verwenden. Warum ist das so? ZusammenfassenDies ist das Ende dieses Artikels über die Probleme, die bei der Implementierung von Vue-Plug-Ins aufgetreten sind. Weitere relevante Probleme bei der Implementierung von Vue-Plug-Ins 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:
|
<<: IIS-Konfiguration des Win Server 2019-Servers und einfache Veröffentlichung der Website
>>: Lösung für das Problem des Datenverlusts bei Verwendung der Ersetzungsoperation in MySQL
Bei Webdiensten geht es um die Kommunikation zwis...
Bei der Verwendung von Nginx als Reverse-Proxy fü...
1. Ich habe lange im Internet gesucht, konnte abe...
Dieser Artikel veranschaulicht anhand von Beispie...
Inhaltsverzeichnis 1. Anwendungslebenszyklus 2. S...
Heute habe ich mich beim Server angemeldet und mi...
CAST-Funktion Im vorherigen Artikel haben wir die...
Inhaltsverzeichnis 1. filter() 2. fürJedes() 3. e...
Inhaltsverzeichnis Was ist die Listener-Eigenscha...
Ich bin vor kurzem mit MySQL in Berührung gekomme...
Inhaltsverzeichnis 1. Das Konzept des Filters 1. ...
MySQL-Zeilen-zu-Spalten-Operation Die sogenannte ...
Inhaltsverzeichnis Nginx-Lastausgleichskonfigurat...
Ich habe in letzter Zeit viel Wissen und Artikel ...
1. Funktion Wird hauptsächlich verwendet, um den ...