22 Vue-Optimierungstipps (Projektpraxis)

22 Vue-Optimierungstipps (Projektpraxis)

Der Demonstrationscode ist in Vue3 + ts + Vite geschrieben, es werden jedoch auch auf Vue2 anwendbare Optimierungstechniken aufgeführt. Wenn eine Optimierung nur auf Vue3 oder Vue2 anwendbar ist, werde ich dies im Titel kennzeichnen.

Code-Optimierung

Verwenden der Taste in v-for

Wenn v-for zum Aktualisieren einer gerenderten Elementliste verwendet wird, wird die standardmäßige In-Place-Wiederverwendungsstrategie verwendet. Wenn die Listendaten geändert werden, wird anhand des Schlüsselwerts ermittelt, ob ein Wert geändert wurde. Wenn geändert, wird dieses Element erneut gerendert, andernfalls wird das vorherige Element wiederverwendet.

Hinweise zur Verwendung von Schlüsseln:

  • Verwenden Sie keine Schlüsselwerte, die sich wiederholen oder ändern können (die Konsole gibt auch eine Erinnerung)
  • Verwenden Sie den Array-Index nicht als Schlüsselwert, da sich der Index der nachfolgenden Elemente ändert, wenn Sie ein Element in das Array einfügen.
  • Wenn im Array kein eindeutiger Schlüsselwert verfügbar ist, können Sie zur Gewährleistung der Eindeutigkeit ein Schlüsselfeld mit dem Wert Symbol() hinzufügen.

Verwenden des Schlüssels in v-if/v-else-if/v-else

Vielleicht werden viele Leute diesen Punkt ignorieren.

Grund: Standardmäßig aktualisiert Vue das DOM so effizient wie möglich. Dies bedeutet, dass beim Wechseln zwischen Elementen desselben Typs das vorhandene Element gepatcht wird, anstatt das alte zu entfernen und an derselben Stelle ein neues hinzuzufügen. Werden nicht identische Elemente als identisch erkannt, kann es zu unerwarteten Nebenwirkungen kommen.

Wenn nur ein v-if und kein v-else oder v-if-else vorhanden ist, muss kein Schlüssel hinzugefügt werden.

Im Vergleich zum Schlüssel von v-for ist der Schlüssel in v-if/v-else-if/v-else relativ einfach. Wir können direkt einen festen String oder ein Array schreiben.

  <Übergang>
    <Schaltfläche 
      v-if="wird bearbeitet"
      v-on:click="istBearbeiten = false"
    >
      Speichern
    </button>
    <Schaltfläche 
      v-sonst 
      v-on:click="istBearbeiten = true"
    >
      Bearbeiten
    </button>
  </Übergang>
.v-enter-active, .v-leave-active {
  Übergang: alles 1en;
}
.v-eintreten, .v-verlassen-zu {
  Deckkraft: 0;
  transformieren: übersetzenY(30px);
}
.v-aktiv lassen {
  Position: absolut;
}

Im obigen Code werden Sie beispielsweise feststellen, dass der Übergang nicht ausgelöst werden kann, wenn der Schlüsselschalter nicht hinzugefügt wird, obwohl der Übergangseffekt zur Schaltfläche hinzugefügt wird.
Verwenden Sie v-for und v-if nicht zusammen (Vue2).

Diese Optimierungstechnik ist auf Vue2 beschränkt. Die Priorität von v-for und v-if wurde in Vue3 angepasst.

Jeder weiß das

Verwenden Sie niemals v-if und v-for für dasselbe Element. Siehe Vue 2.x Style Guide

Der Grund dafür ist, dass v-for eine höhere Priorität als v-if hat. Wenn sie also auf demselben Tag verwendet werden, wird jedes Rendering zuerst wiederholt und dann die bedingte Beurteilung durchgeführt.

Hinweis: v-if hat in Vue3 eine höhere Priorität als v-for. Wenn v-for und v-if also zusammen verwendet werden, ist der Effekt ähnlich dem Effekt der Erhöhung von v-if in Vue2.

Beispielsweise wird der folgende Code in Vue2 nicht empfohlen, und Vue gibt auch eine entsprechende Warnung aus

<ul>
  <li v-for="Benutzer in Benutzern" v-if="Benutzer.aktiv">
    {{ Benutzername }}
  </li>
</ul>

Wir sollten versuchen, v-if auf die obere Ebene zu verschieben oder berechnete Eigenschaften zur Datenverarbeitung zu verwenden

<ul v-if="aktiv">
  <li v-for="Benutzer in Benutzer">
    {{ Benutzername }}
  </li>
</ul>

Wenn Sie nicht möchten, dass die Schleife einen unnötigen übergeordneten Container hat, können Sie als übergeordnetes Element eine Vorlage verwenden. Die Vorlage wird vom Browser nicht als DOM-Knoten gerendert. Wenn ich den Inhalt jedes Elements im Traversierungsobjekt bestimmen möchte, um die gerenderten Daten auszuwählen, kann ich „computed“ verwenden, um das Traversierungsobjekt zu filtern.

// js
let usersActive = berechnet(()=>users.filter(Benutzer => user.active))

// Vorlage
<ul>
    <li v-for="Benutzer in usersActive">
      {{ Benutzername }}
    </li>
</ul>

Sinnvolle Wahl von v-if und v-show

Jeder kennt den Unterschied zwischen v-if und v-show. v-if steuert das Anzeigen und Ausblenden von Elementen durch direktes Manipulieren des Löschens und Hinzufügens von DOM. v-show steuert das Anzeigen und Ausblenden von Elementen durch Steuern der Anzeige-CSS von DOM. Da die Leistung von Hinzufügungs-/Löschvorgängen auf DOM viel geringer ist als die der Manipulation von CSS-Eigenschaften von DOM, verwenden wir v-show zur Leistungssteigerung, wenn Elemente häufig angezeigt/ausgeblendet werden müssen.
Wenn ein Element nicht häufig angezeigt/ausgeblendet werden muss, können wir das DOM über v-if entfernen, um die vom Browser zum Rendern dieses Teils des DOM benötigten Ressourcen zu sparen.

Verwenden einfacher berechneter Eigenschaften

Komplexe berechnete Eigenschaften sollten in möglichst viele einfachere Eigenschaften aufgeteilt werden.

Wenn jede berechnete Eigenschaft aus einem sehr einfachen Ausdruck mit wenigen Abhängigkeiten besteht, ist es einfacher, Tests zu schreiben, um sicherzustellen, dass sie korrekt funktioniert.

Leichter zu lesen: Vereinfachte berechnete Eigenschaften erfordern, dass Sie jedem Wert einen beschreibenden Namen geben, auch wenn er nicht wiederverwendbar ist. Dadurch können sich andere Entwickler (und Sie in Zukunft auch) leichter auf den Code konzentrieren, der für sie wichtig ist, und herausfinden, was los ist.

Besser „Veränderungen annehmen“
Jeder Wert, der benannt werden kann, kann in einer Ansicht verwendet werden. Beispielsweise möchten wir dem Benutzer möglicherweise eine Meldung anzeigen, die ihn darüber informiert, wie viel Geld er gespart hat. Wir möchten möglicherweise auch Steuern berechnen, diese aber vielleicht separat und nicht als Teil des Gesamtpreises anzeigen.
Kleine, fokussierte berechnete Eigenschaften reduzieren die Annahmen, die bei der Verwendung von Informationen getroffen werden müssen, sodass bei sich ändernden Anforderungen weniger Refactoring erforderlich ist.

Siehe Vue2 Style Guide

„Computed“ ist jedem bekannt. Es wird neu berechnet, wenn sich die reaktiven Daten ändern, von denen es in seinem Ausdruck abhängt. Wenn wir einen komplexeren Ausdruck in eine berechnete Eigenschaft schreiben, erhöht sich auch die Anzahl der abhängigen reaktiven Daten beliebig. Wenn sich eine der Abhängigkeiten ändert, muss der gesamte Ausdruck neu berechnet werden.

lass Preis = berechnet(()=>{
  sei Basispreis = Herstellungskosten / (1 - Gewinnspanne)
  zurückkehren (
      Basispreis -
      Basispreis * (Rabattprozentsatz || 0)
  )
})

Wenn sich die Herstellungskosten, die Gewinnspanne oder der Rabattprozentsatz ändern, wird der gesamte Preis neu berechnet.
Aber wenn wir es wie folgt ändern

let basePrice = berechnet(() => Herstellungskosten / (1 - Gewinnspanne))
let discount = calculated(() => Basispreis * (Rabattprozentsatz || 0))
let finalPrice = berechnet(() => Basispreis - Rabatt)

Wenn sich discountPercent ändert, werden nur discount und finalPrice neu berechnet. Aufgrund der Caching-Funktion von computed wird basePrice nicht neu berechnet.

Funktionale Komponenten (Vue2)

Beachten Sie, dass dies nur eine Optimierung in Vue2 ist. In 3.x wurde der Leistungsunterschied zwischen zustandsbehafteten und funktionalen Komponenten stark reduziert und ist in den meisten Anwendungsfällen vernachlässigbar. Daher besteht der Migrationspfad für Entwickler, die Funktionalität auf SFCs verwenden, darin, dieses Attribut zu entfernen und alle Referenzen von Props in $props und von Attrs in $attrs umzubenennen.

Vor der Optimierung

<Vorlage> 
    <div Klasse="Zelle"> 
        <div v-if="Wert" Klasse="ein"></div> 
        <Abschnitt v-else class="aus"></Abschnitt> 
    </div> 
</Vorlage>

<Skript> 
Standard exportieren { 
    Requisiten: ['Wert'], 
} 
</Skript>

Nach der Optimierung

<funktionale Vorlage> 
    <div Klasse="Zelle"> 
        <div v-if="props.value" Klasse="ein"></div> 
        <Abschnitt v-else class="aus"></Abschnitt> 
    </div> 
</Vorlage>

<Skript> 
Standard exportieren { 
    Requisiten: ['Wert'], 
} 
</Skript>

  • Nein dies (keine Instanz)
  • Keine Antwortdaten

Komponenten teilen

Was? Eine von Ihnen geschriebene Vue-Datei hat mehr als tausend Codezeilen? 🤔
Durch eine sinnvolle Aufteilung der Komponenten lässt sich nicht nur die Performance optimieren, sondern der Code wird auch übersichtlicher und lesbarer. Einzelfunktionsprinzip

Quelle: https://slides.com/akryum/vueconfus-2019#/4/0/3

Vor der Optimierung

<Vorlage>
  <div :style="{ Deckkraft: Zahl / 300 }">
    <div>{{ schwer() }}</div>
  </div>
</Vorlage>

<Skript>
Standard exportieren {
  Requisiten: ['Zahl'],
  Methoden: {
    heavy () { /* SCHWERE AUFGABE */ }
  }
}
</Skript>

Nach der Optimierung

<Vorlage>
  <div :style="{ Deckkraft: Zahl / 300 }">
    <UntergeordneteKomponente/>
  </div>
</Vorlage>

<Skript>
Standard exportieren {
  Requisiten: ['Zahl'],
  Komponenten:
    Kinderkompatibilität: {
      Methoden: {
        heavy () { /* SCHWERE AUFGABE */ }
      },
      rendern (h) {
        gibt h zurück('div', this.heavy())
      }
    }
  }
}
</Skript>

Da Vue auf Komponentenebene aktualisiert, wird ChildComp nicht erneut gerendert, da darin keine reaktionsfähige Datenänderung vorliegt, obwohl jeder Frame dazu führt, dass die übergeordnete Komponente durch Datenänderung erneut gerendert wird. Die optimierte Komponente führt also nicht bei jedem Rendering zeitaufwändige Aufgaben aus

Verwenden lokaler Variablen

Vor der Optimierung

<Vorlage>
  <div :style="{ Deckkraft: Start / 300 }">{{ Ergebnis }}</div>
</Vorlage>

<Skript>
importiere { heavy } von '@/utils'

Standard exportieren {
  Requisiten: ['Start'],
  berechnet: {
    Basis () { return 42 },
    Ergebnis () {
      let ergebnis = this.start
      für (sei i = 0; i < 1000; i++) {
        Ergebnis += schwer(diese.Basis)
      }
      Ergebnis zurückgeben
    }
  }
}
</Skript>

Nach der Optimierung

<Vorlage>
  <div :style="{ Deckkraft: start / 300 }">
    {{ Ergebnis }}</div>
</Vorlage>

<Skript>
importiere { heavy } von '@/utils'

Standard exportieren {
  Requisiten: ['Start'],
  berechnet: {
    Basis () { return 42 },
    Ergebnis () {
      const base = diese.base
      let ergebnis = this.start
      für (sei i = 0; i < 1000; i++) {
        Ergebnis += schwer(Basis)
      }
      Ergebnis zurückgeben
    }
  }
}
</Skript>

Der Hauptunterschied besteht hier in der Implementierungsdifferenz des berechneten Eigenschaftsergebnisses der Komponenten vor und nach der Optimierung. Die Komponente vor der Optimierung greift während des Berechnungsprozesses viele Male auf this.base zu, während die Komponente nach der Optimierung vor der Berechnung die lokale Variable base verwendet, this.base zwischenspeichert und dann direkt auf base zugreift.

Warum führt dieser Unterschied also zu Leistungsunterschieden? Der Grund dafür ist, dass jedes Mal, wenn Sie auf this.base zugreifen, dessen Getter ausgelöst wird, da this.base ein responsives Objekt ist, und dann der mit der Abhängigkeitssammlung verbundene Logikcode ausgeführt wird. Wenn eine ähnliche Logik zu oft ausgeführt wird, wie im Beispiel, wo Hunderte von Komponenten in Hunderten von Zyklen aktualisiert werden, jede Komponente eine Neuberechnung der Berechnung auslöst und dann die mit der Abhängigkeitssammlung verbundene Logik mehrere Male ausgeführt wird, nimmt die Leistung natürlich ab.

Aus Sicht der Nachfrage reicht es aus, wenn this.base einmal eine Abhängigkeitssammlung durchführt und das Ergebnis seiner Getter-Auswertung an die lokale Variable base zurückgibt. Wenn später erneut auf base zugegriffen wird, wird der Getter nicht ausgelöst und die Abhängigkeitssammlungslogik wird nicht befolgt, sodass die Leistung natürlich verbessert wird.

Führen Sie zur Offenlegung der neun Tipps zur Leistungsoptimierung von Vue.js

Verwenden von KeepAlive

Wenn einige Komponenten mit hohen Rendering-Kosten häufig umgeschaltet werden müssen, kann Keep-Alive zum Zwischenspeichern der Komponente verwendet werden. Nach der Verwendung von Keep-Alive werden der Vnode und der DOM der von Keep-Alive umschlossenen Komponente nach dem ersten Rendering zwischengespeichert. Wenn die Komponente das nächste Mal erneut gerendert wird, werden der entsprechende Vnode und der DOM direkt aus dem Cache abgerufen und dann gerendert. Es ist nicht erforderlich, eine Reihe von Prozessen wie Komponenteninitialisierung, Rendering und erneutes Patchen zu durchlaufen, was die Skriptausführungszeit verkürzt und die Leistung verbessert.

Hinweis: Der Missbrauch von Keep-Alive führt nur zu Verzögerungen Ihrer App, da sie über einen langen Zeitraum eine große Menge an Speicher belegt.

Zerstörung von Ereignissen

Wenn eine Komponente zerstört wird, sollten wir die der Komponente hinzugefügten globalen Ereignisse und Timer löschen, um Speicherlecks zu verhindern.
Mit Vue3s HOOK können wir Ereignisdeklaration und -zerstörung zusammen schreiben, was lesbarer ist

Funktion scrollFun(){ /* ... */}
document.addEventListener("scrollen", scrollFun)

beiVorUnmount(()=>{
  document.removeEventListener("scrollen", scrollFun)
})

Vue2 kann diesen Effekt immer noch durch $once erreichen. Natürlich können Sie das Ereignis auch in optionsAPI beforeDestroy zerstören, aber ich empfehle eher Ersteres, da Letzteres den Code mit derselben Funktion noch unübersichtlicher macht.

Funktion scrollFun(){ /* ... */}
document.addEventListener("scrollen", scrollFun)

dies.$once('hook:beforeDestroy', ()=>{
  document.removeEventListener("scrollen", scrollFun)
})

Funktion scrollFun(){ /* ... */}

Standard exportieren {
  erstellt() {
    document.addEventListener("scrollen", scrollFun)
  },
  vorZerstören(){
    document.removeEventListener("scrollen", scrollFun)
  }
}

Bild wird geladen

Lazy Loading von Bildern: Geeignet für Situationen, in denen sich auf der Seite viele Bilder befinden und nicht alle Bilder auf einem Bildschirm angezeigt werden. Das Plug-In vue-lazyload bietet uns eine sehr praktische Anweisung zum Lazy Loading von Bildern v-lazy

Allerdings sind nicht alle Bilder für Lazy Loading geeignet. Für Banner und Fotoalben empfiehlt es sich beispielsweise, die Bildvorladetechnologie zu verwenden, um dem Herunterladen des vorherigen und nächsten Bildes des aktuell angezeigten Bildes Priorität einzuräumen.

Verwenden Sie sinnvolle Datenverarbeitungsalgorithmen

Dies ist ein relativer Test des Wissens über Datenstruktur und Algorithmus. Beispielsweise eine Methode zum Konvertieren eines Arrays in eine mehrstufige Struktur

/**
 * Array zu Baumstruktur, Zeitkomplexität O(n)
 * @param Listen-Array * @param idKey Element-ID-Schlüssel * @param parIdKey Element-Eltern-ID-Schlüssel * @param parId Eltern-ID-Wert des Stammknotens der ersten Ebene * @return {[]}
 */
Funktion listToTree (Liste, ID-Schlüssel, ParId-Schlüssel, ParId) {
    lass map = {};
    lass Ergebnis = [];
    let len ​​= list.length;

    // Karte erstellen
    für (sei i = 0; i < len; i++) {
        //Konvertiere die Daten im Array in eine Schlüssel-Wert-Paarstruktur (das Array und das Objekt verweisen hier aufeinander, was der entscheidende Punkt bei der Implementierung des Algorithmus ist)
        Karte[Liste[i][idKey]] = Liste[i];
    }

    //Baumarray erstellen for(let i=0; i < len; i++) {
        let itemParId = Liste[i][parIdKey];
        // Knoten der obersten Ebene if(itemParId === parId) {
            Ergebnis.push(Liste[i]);
            weitermachen;
        }
        // Verwaister Knoten, verworfen (es existiert kein übergeordneter Knoten)
        wenn(!map[itemParId]){
            weitermachen;
        }
        //Füge den aktuellen Knoten in die untergeordneten Knoten des übergeordneten Knotens ein (da es sich um einen Referenzdatentyp handelt, ändert sich der entsprechende Knoten im Ergebnis entsprechend, wenn sich der Knoten in obj ändert)
        wenn(map[itemParId].children) {
            Karte[itemParId].children.push(Liste[i]);
        } anders {
            Karte[itemParId].children = [Liste[i]];
        }
    }
    Ergebnis zurückgeben;
}

andere

Neben den oben genannten Methoden gibt es noch viele weitere Optimierungstechniken, die ich in meinen Projekten jedoch nicht allzu oft verwende🤣

  • Objekte einfrieren (um zu verhindern, dass unnötige Reaktionsdaten responsiv werden)
  • Rendern langer Listen - Batch-Rendering
  • Rendering langer Listen – dynamisches Rendering (Vue-Virtual-Scroller)
  • ...

Erster Bildschirm/Volumenoptimierung

In meinem Projekt habe ich hauptsächlich folgende Optimierungsrichtungen für die erste Bildschirmoptimierung

  • Volumen
  • Code-Aufteilung
  • Netzwerk

Volumenoptimierung

  • Komprimieren Sie den gebündelten Code: Die Produktionsumgebungsverpackung von webpack und vite komprimiert Ihren Code standardmäßig. Dies erfordert im Allgemeinen keine spezielle Verarbeitung. Webpack kann dies auch manuell über das entsprechende Komprimierungs-Plugin implementieren.
  • Quellzuordnung abbrechen: Sie können prüfen, ob in Ihrem verpackten Produkt eine .map-Datei vorhanden ist. Wenn ja, können Sie den Wert von Quellzuordnung auf „false“ oder „leer“ setzen, um die Codezuordnung auszuschalten (dies nimmt viel Platz ein).
  • Gizp-Komprimierung für Verpackung aktivieren: Dazu muss der Server auch die Gizp-Übertragung aktivieren, andernfalls ist die Aktivierung nutzlos (webpack verfügt über ein entsprechendes GZIP-Komprimierungs-Plugin, verschiedene Versionen der Webpack-Komprimierungs-Plugins können unterschiedlich sein, es wird empfohlen, zuerst die offizielle Website zu überprüfen).

Code-Aufteilung

Die Funktion der Codeaufteilung besteht darin, das verpackte Produkt nacheinander in kleine Produkte aufzuteilen, was von esModule abhängt. Wenn Sie also die Funktion import() zum Importieren einer Datei oder Abhängigkeit verwenden, wird die Datei oder Abhängigkeit separat als kleines Produkt verpackt. Sowohl das Lazy Loading von Routen als auch asynchrone Komponenten nutzen dieses Prinzip.

  • Routing für verzögertes Laden
  • Asynchrone Komponenten

Für UI-Bibliotheken verwende ich grundsätzlich kein On-Demand-Laden von Komponenten, sondern bevorzuge die Optimierung durch Bereitstellung über CDN.

Netzwerk

  • CDN: Zunächst wird wie oben erwähnt das CDN eingeführt. Dabei werden in der Entwicklungsphase lokale Bibliotheken verwendet und beim Paketieren durch die Konfiguration externer Erweiterungen (Externals) diese Abhängigkeiten ausgeschlossen. Importieren Sie sie dann über CDN in die HTML-Datei
  • Server-Push: HTTP2 ist relativ ausgereift. Nach der oben erwähnten Einführung des CDN können wir die Server-Push-Funktion von HTTP2 auf der Website verwenden, damit der Browser diese CDN- und andere Dateien im Voraus lädt.
  • Gzip aktivieren: Dies wurde oben erwähnt. Das Prinzip besteht darin, dass, wenn sowohl der Client als auch der Server die Gzip-Übertragung unterstützen, der Server dem Senden von mit Gzip komprimierten Dateien Vorrang einräumt und der Client sie nach dem Empfang dekomprimiert.
  • Caching aktivieren: Normalerweise verwende ich ausgehandeltes Caching, aber das gilt nicht für alle Situationen. Beispielsweise können Sie die Dateinamen von Dateien, die Server Push verwenden, nicht beliebig ändern. Daher fixiere ich normalerweise den Dateinamen der Hauptdatei

Damit ist dieser Artikel über 22 Vue-Optimierungstechniken (praktisch für Projekte) abgeschlossen. Weitere relevante Vue-Optimierungstechniken 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:
  • Einige Tipps zur Verwendung von Less in Vue-Projekten
  • Vue.js Leistungsoptimierung N Tipps (es lohnt sich, sie zu sammeln)
  • Zusammenfassung praktischer Fähigkeiten, die häufig in Vue-Projekten verwendet werden
  • Zusammenfassung von 10 erweiterten Tipps für Vue Router
  • 8 Tipps für Vue, die Sie nach dem Lesen lernen werden
  • Tipps zur Verwendung von Vue-Elementen und Nuxt
  • Zusammenfassung gängiger Routinen und Techniken in der Vue-Entwicklung
  • Eine kurze Diskussion über die Verwendung von Vue-Funktionskomponenten
  • 6 Tipps zum Schreiben besserer v-for-Schleifen in Vue.js
  • 25 Vue-Tipps, die Sie kennen müssen

<<:  So stellen Sie mit C++ eine Verbindung zu MySQL her

>>:  Verschönerung der Dualsystem-Boot-Schnittstelle für Win10 + Ubuntu20.04 LTS

Artikel empfehlen

So implementieren Sie Vue Page Jump

1. dies.$router.push() 1. Ansicht <Vorlage>...

Detaillierte Analyse des React Diff-Prinzips

Inhaltsverzeichnis Diffing-Algorithmus Schicht-fü...

MySQL-Optimierung Verbindungsoptimierung

Im Artikel MySQL-Optimierung: Cache-Optimierung w...

Zusammenfassung mehrerer häufig verwendeter CentOS7-Images basierend auf Docker

Inhaltsverzeichnis 1 Docker installieren 2 Konfig...

Die Element-UI-Tabelle realisiert die Dropdown-Filterfunktion

In diesem Artikelbeispiel wird der spezifische Co...

UrlRewriter-Caching-Probleme und eine Reihe damit verbundener Untersuchungen

Beim Entwickeln einer Website-Funktion kann der S...

JavaScript zum Erzielen eines Tab-Umschalteffekts

In diesem Artikel wird der spezifische JavaScript...

Beispiel für die Bereitstellungsmethode „Forever+nginx“ einer Node-Site

Ich habe vor Kurzem den günstigsten Tencent-Cloud...