Da die Geschäftsfunktionen von Front-End-Anwendungen immer komplexer werden und die Anforderungen der Benutzer an das Benutzererlebnis immer höher werden, haben sich Single-Page-Anwendungen (SPA) zur Mainstream-Form von Front-End-Anwendungen entwickelt. Eines der bemerkenswertesten Merkmale großer Single-Page-Anwendungen ist die Verwendung eines Front-End-Routingsystems, das Seitenaufrufe durch Ändern der URL aktualisiert, ohne die Seite erneut anzufordern. „Aktualisieren der Ansicht ohne erneute Seitenanforderung“ ist eines der Kernprinzipien des Front-End-Routings. Derzeit gibt es zwei Hauptmethoden, um diese Funktion in der Browserumgebung zu implementieren:
vue-router ist ein Routing-Plugin für das Vue.js-Framework. Beginnen wir mit dem Quellcode, lesen den Code und die Prinzipien und lernen von oberflächlich nach tiefer, wie vue-router Front-End-Routing mithilfe dieser beiden Methoden implementiert. ModusparameterIm Vue-Router wird der Modusparameter verwendet, um den Routing-Implementierungsmodus zu steuern: const router = neuer VueRouter({ Modus: "Verlauf", Routen: [...] }) Beim Erstellen eines Instanzobjekts von VueRouter wird der Modus als Konstruktorparameter übergeben. Wenn wir den Quellcode mit Fragen im Hinterkopf lesen, können wir mit der Definition der VueRouter-Klasse beginnen. Im Allgemeinen werden die vom Plug-In bereitgestellten Klassen in der Datei index.js im Stammverzeichnis des Quellcodes src definiert. Öffnen Sie die Datei und Sie können die Definition der VueRouter-Klasse sehen. Die Auszüge zum Modusparameter lauten wie folgt: exportiere Standardklasse VueRouter { mode: string; // Der übergebene String-Parameter gibt die Verlaufskategorie anhistory: HashHistory | HTML5History | AbstractHistory; // Die Objekteigenschaft, die tatsächlich funktioniert, muss eine Aufzählung der drei oben genannten Klassen seinfallback: boolean; // Wenn der Browser dies nicht unterstützt, muss der Modus „history“ auf den Modus „hash“ zurückgesetzt werdenconstructor (options: RouterOptions = {}) { let mode = options.mode || 'hash' // Standardmäßig ist der Modus 'hash' this.fallback = mode === 'history' && !supportsPushState // Verwenden Sie supportsPushState, um zu ermitteln, ob der Browser den Modus 'history' unterstützt if (this.fallback) { Modus = "Hash" } wenn (!imBrowser) { mode = 'abstract' // Wenn es nicht in einer Browserumgebung ausgeführt wird, erzwingen Sie den Modus 'abstract'} this.mode = Modus // Bestimmen Sie die tatsächliche Klasse der Historie basierend auf dem Modus und instanziieren Sie den Schalter (Modus) { Anamnese': diese.History = neue HTML5History(diese, Optionen.Basis) brechen Fall 'Hash': diese.History = neue HashHistory(diese, Optionen.Basis, diese.Fallback) brechen Fall 'abstrakt': diese.History = neue AbstractHistory(diese, options.base) brechen Standard: wenn (Prozess.Umgebung.NODE_ENV !== 'Produktion') { assert(false, `ungültiger Modus: ${mode}`) } } } init (app: any /* Vue-Komponenteninstanz */) { const history = diese.geschichte // Führen Sie die entsprechenden Initialisierungsvorgänge und die Überwachung entsprechend der Verlaufskategorie durch, wenn (Verlaufsinstanz von HTML5History) { Verlauf.Übergang zu(Verlauf.getCurrentLocation()) } sonst wenn (History-Instanz von HashHistory) { const setupHashListener = () => { Verlauf.setupListeners() } Verlauf.ÜbergangZu( Verlauf.getCurrentLocation(), setupHashListener, HashListener einrichten ) } Verlauf.listen(route => { diese.apps.forEach((app) => { app._route = Route }) }) } // Die folgende von der VueRouter-Klasse bereitgestellte Methode ruft tatsächlich die Methode des spezifischen Verlaufsobjekts push (location: RawLocation, onComplete?: Function, onAbort?: Function) { auf. this.history.push(Standort, bei Abschluss, bei Abbruch) } ersetzen (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { this.history.replace(Standort, bei Abschluss, bei Abbruch) } } Man kann Folgendes erkennen: Der als Parameter übergebene String-Attributmodus ist lediglich ein Marker, der die Implementierungsklasse des Objektattributverlaufs angibt, die tatsächlich funktioniert. Die entsprechende Beziehung zwischen den beiden ist wie folgt:
Vor dem Initialisieren des entsprechenden Verlaufs werden einige Prüfungen des Modus durchgeführt: Wenn der Browser die Methode HTML5History nicht unterstützt (beurteilt durch die Variable „supportsPushState“), wird der Modus zwangsweise auf „Hash“ gesetzt; wenn er nicht in einer Browserumgebung ausgeführt wird, wird der Modus zwangsweise auf „Abstrakt“ gesetzt. Die Methoden onReady(), push() und andere in der VueRouter-Klasse sind nur Proxys. Sie rufen tatsächlich die entsprechenden Methoden des spezifischen Verlaufsobjekts auf. Bei der Initialisierung in der Methode init() werden je nach spezifischer Kategorie des Verlaufsobjekts unterschiedliche Vorgänge ausgeführt. Die beiden Methoden in der Browserumgebung werden in den Klassen HTML5History bzw. HashHistory implementiert. Sie sind alle im Ordner „src/history“ definiert und erben von der History-Klasse, die in der Datei „base.js“ im selben Verzeichnis definiert ist. History definiert allgemeine und grundlegende Methoden, deren direktes Lesen verwirrend sein kann. Beginnen wir mit den bekannten Methoden push() und replace() in den Klassen HTML5History und HashHistory. HashHistorieLassen Sie uns zunächst das Prinzip wiederholen, bevor wir uns den Quellcode ansehen: Das Rautezeichen („#“) wird ursprünglich zur URL hinzugefügt, um den Speicherort der Webseite anzugeben: www.example.com/index.html#… Das #-Symbol selbst und die ihm folgenden Zeichen werden als Hash bezeichnet und können über die Eigenschaft window.location.hash gelesen werden. Es verfügt über die folgenden Funktionen:
window.addEventListener("hashchange", funcRef, false) Jedes Mal, wenn der Hash (window.location.hash) geändert wird, wird dem Zugriffsverlauf des Browsers ein Datensatz hinzugefügt. Durch die Verwendung der oben genannten Hash-Eigenschaften können Sie im Front-End-Routing die Funktion „Ansicht aktualisieren, aber Seite nicht erneut anfordern“ implementieren. HashHistory.push()Schauen wir uns die push()-Methode in HashHistory an: push (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { dies.transitionTo(Standort, Route => { pushHash(route.vollständigerPfad) beiAbgeschlossen und beiAbgeschlossen(Route) }, beiAbbruch) } Funktion pushHash (Pfad) { window.location.hash = Pfad } Die Methode transitionTo() ist in der übergeordneten Klasse definiert, um die grundlegende Logik von Routenänderungen zu handhaben. Die Methode push() wird hauptsächlich verwendet, um den Hash des Fensters direkt zuzuweisen: Fenster.Standort.Hash = Route.vollständigerPfad Änderungen am Hash werden automatisch in die Zugriffshistorie des Browsers eingetragen. Wie wird die Ansicht aktualisiert? Schauen wir uns die Methode transitionTo() in der übergeordneten Klasse History an: transitionTo (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { const route = dieser.router.match(Standort, dieser.aktuell) dies.confirmTransition(route, () => { dies.updateRoute(route) ... }) } updateRoute (Route: Route) { dies.cb und dies.cb(Route) } listen (cb: Funktion) { dies.cb = cb } Wie Sie sehen, wird bei einer Änderung der Route die Methode this.cb in History aufgerufen und die Methode this.cb über History.listen(cb) festgelegt. Als wir zur Klassendefinition von VueRouter zurückkehrten, stellten wir fest, dass sie in der Methode init() festgelegt wurde: init (app: any /* Vue-Komponenteninstanz */) { this.apps.push(app) Verlauf.listen(route => { diese.apps.forEach((app) => { app._route = Route }) }) } Den Kommentaren zufolge ist app eine Vue-Komponenteninstanz, aber wir wissen, dass Vue als progressives Front-End-Framework kein integriertes Routenattribut _route in seiner Komponentendefinition haben sollte. Wenn die Komponente dieses Attribut benötigt, sollte es in das Vue-Objekt an der Stelle eingemischt werden, an der das Plug-In geladen wird, d. h. in der install()-Methode von VueRouter. Überprüfen Sie den Quellcode von install.js, dort gibt es den folgenden Absatz: Exportfunktion installieren (Vue) { Vue.mixin({ vorErstellen () { wenn (isDef(this.$options.router)) { dieser._router = dieser.$options.router dies._router.init(dies) Vue.util.defineReactive(dies, '_route', dies._router.history.current) } registerInstance(dies, dies) }, }) } Durch die Methode Vue.mixin() wird ein Mixin global registriert, was sich auf jede nach der Registrierung erstellte Vue-Instanz auswirkt. Das Mixin definiert ein responsives _route-Attribut durch Vue.util.defineReactive() im beforeCreate-Hook. Die sogenannte responsive Eigenschaft bedeutet, dass bei einer Änderung des _route-Werts automatisch die render()-Methode der Vue-Instanz aufgerufen wird, um die Ansicht zu aktualisieren. Zusammenfassend lässt sich sagen, dass der Vorgang vom Festlegen von Routenänderungen bis zum Anzeigen von Updates wie folgt abläuft: $router.push() --> HashHistory.push() --> History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render() HashHistory.replace()Die Methode replace() unterscheidet sich von der Methode push() darin, dass sie die neue Route nicht oben im Zugriffsverlaufsstapel des Browsers hinzufügt, sondern die aktuelle Route ersetzt: ersetzen (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { dies.transitionTo(Standort, Route => { replaceHash(route.vollständigerPfad) beiAbgeschlossen und beiAbgeschlossen(Route) }, beiAbbruch) } Funktion replaceHash (Pfad) { const i = Fenster.Standort.href.indexOf('#') Fenster.Standort.Ersetzen( window.location.href.slice(0, i >= 0 ? i : 0) + '#' + Pfad ) } Es ist ersichtlich, dass seine Implementierungsstruktur grundsätzlich der von push () ähnelt. Der Unterschied besteht darin, dass window.location.hash nicht direkt ein Wert zugewiesen wird, sondern die Methode window.location.replace aufgerufen wird, um die Route zu ersetzen. Hören Sie auf die AdressleisteDie oben besprochenen VueRouter.push() und VueRouter.replace() können direkt im Logikcode der Vue-Komponente aufgerufen werden. Darüber hinaus können Benutzer im Browser auch Änderungen an der Route direkt in die Adressleiste des Browsers eingeben. Daher muss VueRouter auch in der Lage sein, Änderungen an der Route in der Adressleiste des Browsers zu überwachen und dasselbe Antwortverhalten wie beim Aufruf über Code zu haben. In HashHistory wird diese Funktion über setupListeners implementiert: setupListeners() { window.addEventListener('hashchange', () => { wenn (!ensureSlash()) { zurückkehren } dies.transitionTo(getHash(), route => { replaceHash(route.vollständigerPfad) }) }) } Diese Methode legt das Browserereignis „Hashchange“ als Listener fest und die aufgerufene Funktion ist „replaceHash“, d. h. die direkte Eingabe der Route in die Adressleiste des Browsers entspricht dem Aufruf der Methode „replace ()“ im Code. HTML5GeschichteDie Verlaufsschnittstelle ist die vom Browserverlaufsstapel bereitgestellte Schnittstelle. Über Methoden wie back (), forward (), go () usw. können wir die Informationen des Browserverlaufsstapels lesen und verschiedene Sprungvorgänge ausführen. Ab HTML5 bietet die History-Schnittstelle zwei neue Methoden: pushState() und replaceState(), mit denen wir den Browserverlaufsstapel ändern können: window.history.pushState(Statusobjekt, Titel, URL) window.history.replaceState(Statusobjekt, Titel, URL)
Diese beiden Methoden haben eine gemeinsame Funktion: Wenn sie aufgerufen werden, um den Browserverlaufsstapel zu ändern, sendet der Browser, obwohl sich die aktuelle URL geändert hat, nicht sofort eine Anforderung an die URL (der Browser versucht nicht, diese URL nach einem Aufruf von pushState() zu laden). Dies bildet die Grundlage für das Front-End-Routing der Single-Page-Anwendung, um „die Ansicht zu aktualisieren, aber die Seite nicht erneut anzufordern“. Schauen wir uns den Quellcode im Vue-Router an: push (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { const { current: fromRoute } = dies dies.transitionTo(Standort, Route => { pushState(saubererPfad(diese.Basis + Route.vollständigerPfad)) handleScroll(dieser.Router, Route, vonRoute, false) beiAbgeschlossen und beiAbgeschlossen(Route) }, beiAbbruch) } ersetzen (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) { const { current: fromRoute } = dies dies.transitionTo(Standort, Route => { replaceState(cleanPath(diese.Basis + Route.vollständigerPfad)) handleScroll(dieser.Router, Route, vonRoute, false) beiAbgeschlossen und beiAbgeschlossen(Route) }, beiAbbruch) } // src/util/push-state.js Exportfunktion pushState (URL?: Zeichenfolge, Ersetzen?: Boolescher Wert) { saveScrollPosition() // Versuchen Sie, den PushState-Aufruf abzufangen, um Safari zu umgehen // DOM-Ausnahme 18, bei der die Anzahl der PushState-Aufrufe auf 100 begrenzt wird const history = fenster.history versuchen { wenn (ersetzen) { history.replaceState({ Schlüssel: _key }, '', URL) } anders { _key = genKey() history.pushState({ Schlüssel: _key }, '', URL) } } fangen (e) { window.location[ersetzen? 'ersetzen': 'zuweisen'](URL) } } Exportfunktion replaceState (URL?: Zeichenfolge) { pushState(URL, wahr) } Die Codestruktur und Logik zum Aktualisieren von Ansichten ähneln grundsätzlich dem Hash-Modus, mit der Ausnahme, dass die direkte Zuweisung von window.location.hash zu window.location.replace() in den Aufruf der Methoden history.pushState() und history.replaceState() geändert wird. Das Hinzufügen eines Listeners zum Ändern der URL in der Adressleiste des Browsers in HTML5History wird direkt im Konstruktor ausgeführt: Konstruktor (Router: Router, Basis: ?string) { window.addEventListener('popstate', e => { const current = dies.aktuell dies.transitionTo(getLocation(this.base), Route => { wenn (erwarteScrollen) { handleScroll(Router, Route, aktuell, wahr) } }) }) } Natürlich verwendet HTML5History neue Funktionen von HTML5, die von einer bestimmten Browserversion unterstützt werden müssen. Wie wir bereits gesehen haben, wird anhand der Variable supportsPushState geprüft, ob der Browser dies unterstützt: // src/util/push-state.js export const supportsPushState = inBrowser && (Funktion () { const ua = window.navigator.userAgent Wenn ( (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1 ) { return false } gibt window.history und „pushState“ in window.history zurück })() Das Obige ist eine Einführung in den Quellcode des Hash-Modus und des Verlaufsmodus. Beide Modi werden über die Browserschnittstelle implementiert. Darüber hinaus bereitet vue-router auch einen abstrakten Modus für Nicht-Browser-Umgebungen vor. Das Prinzip besteht darin, einen Array-Stack zu verwenden, um die Funktion des Browser-Verlaufsstapels zu simulieren. Natürlich handelt es sich bei den oben genannten Punkten nur um einige Kernlogiken. Um die Robustheit des Systems sicherzustellen, enthält der Quellcode viele Hilfslogiken, die ebenfalls erlernt werden sollten. Darüber hinaus gibt es im Vue-Router wichtige Teile wie Routenanpassung und Router-View-Ansichtskomponenten Vergleich der beiden ModiIn allgemeinen Nachfrageszenarien sind der Hash-Modus und der Verlaufsmodus ähnlich, aber fast alle Artikel empfehlen die Verwendung des Verlaufsmodus. Der Grund ist: Das Symbol "#" ist zu hässlich ... 0_0 "
Als gewissenhafte Menschen sollten wir die Qualität einer Technik natürlich nicht anhand des Aussehens beurteilen. Laut MDN hat der Aufruf von history.pushState() gegenüber der direkten Änderung des Hashs folgende Vorteile:
Ein Problem mit dem VerlaufsmodusWir wissen, dass das ideale Nutzungsszenario für Einzelseitenanwendungen darin besteht, index.html nur beim Aufrufen der Anwendung zu laden und nachfolgende Netzwerkvorgänge über Ajax abzuschließen, ohne die Seite gemäß der URL erneut anzufordern. Es ist jedoch unvermeidlich, auf besondere Situationen zu stoßen, z. B. wenn der Benutzer direkt in die Adressleiste eingibt und die Eingabetaste drückt, der Browser neu startet und die Anwendung neu lädt usw. Der Hash-Modus ändert nur den Inhalt des Hash-Teils und der Hash-Teil wird nicht in die HTTP-Anforderung aufgenommen: http://oursite.com/#/user/id // Wenn Sie erneut anfordern, wird nur http://oursite.com/ gesendet Daher gibt es im Hash-Modus keine Probleme, wenn Seiten basierend auf URLs angefordert werden. Der Verlaufsmodus ändert die URL so, dass sie mit der URL des normalen Anforderungs-Backends übereinstimmt. http://oursite.com/user/id Senden Sie in diesem Fall die Anfrage erneut an das Backend. Wenn das Backend nicht mit der entsprechenden /user/id-Routingverarbeitung konfiguriert ist, wird ein 404-Fehler zurückgegeben. Die offiziell empfohlene Lösung besteht darin, serverseitig eine Kandidatenressource hinzuzufügen, um alle Situationen abzudecken: Wenn die URL keiner statischen Ressource entspricht, sollte dieselbe index.html-Seite zurückgegeben werden, also die Seite, von der Ihre App abhängt. Darüber hinaus gibt der Server auf diese Weise keine 404-Fehlerseite mehr zurück, da für alle Pfade die Datei index.html zurückgegeben wird. Um dies zu vermeiden, decken Sie alle Routing-Situationen in der Vue-Anwendung ab und geben Sie dann eine 404-Seite aus. Wenn Sie alternativ Node.js als Backend verwenden, können Sie das serverseitige Routing zum Abgleichen der URL nutzen und 404 zurückgeben, wenn keine Übereinstimmung mit der Route gefunden wird, und so ein Fallback implementieren. Anwendungsdateien direkt laden
Nachdem das Vue-Projekt über das Webpack von Vue-CLI gepackt wurde, wird in der Befehlszeile die folgende Eingabeaufforderung angezeigt. Normalerweise wird auf Front-End-Projekte über den Server zugegriffen, egal ob in der Entwicklung oder online, und es gibt kein „Öffnen von index.html über file://“. Programmierer wissen jedoch alle, dass Anforderungen und Szenarien immer seltsam sind. Es gibt nichts, woran Produktmanager nicht denken können, nur das, woran Sie nicht denken können. Die ursprüngliche Absicht beim Schreiben dieses Artikels bestand darin, auf folgendes Problem zu stoßen: Ich musste schnell ein mobiles Anzeigeprojekt entwickeln und beschloss, WebView zum Laden der Vue-Einzelseitenanwendung zu verwenden, aber es war kein Backend-Server vorhanden, sodass alle Ressourcen aus dem lokalen Dateisystem geladen werden mussten: //AndroidAppWrapper öffentliche Klasse MainActivity erweitert AppCompatActivity { private WebView WebView; @Überschreiben geschützt void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView = neue WebView(diese); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/index.html"); setContentView(webView); } @Überschreiben öffentliches Boolean beiTastennachunten(int Schlüsselcode, Schlüsselereignisereignis) { wenn ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { webView.goBack(); gibt true zurück; } gibt false zurück; } } In diesem Fall muss ich anscheinend "index.html über file:// öffnen", also muss ich zuerst einige Einstellungen vornehmen
Dies ist eine offensichtliche Änderung, die vorgenommen werden muss, aber nach der Änderung kann es immer noch nicht erfolgreich geladen werden. Nach wiederholter Untersuchung wurde festgestellt, dass der Router bei der Entwicklung des Projekts auf den Verlaufsmodus eingestellt war (aus ästhetischen Gründen ... 0_0"). Als er in den Hash-Modus geändert wurde, konnte er normal geladen werden. Warum passiert das? Die Gründe dafür habe ich wie folgt analysiert: Beim direkten Laden von index.html aus dem Dateisystem lautet die URL: Datei:///android_asset/index.html Der Pfad, mit dem die Startseitenansicht übereinstimmen muss, ist der Pfad: '/': exportiere standardmäßig einen neuen Router({ Modus: "Verlauf", Routen: [ { Weg: '/', Name: "Index", Komponente: IndexView } ] }) Schauen wir uns zunächst den Verlaufsmodus in HTML5History an: secureURL ( push?: boolean ) { wenn (getLocation(diese.Basis) !== dieser.aktuelle.vollständigerPfad) { const current = cleanPath(diese.Basis + dies.aktueller.vollerPath) pushen? pushState(aktuell) : replaceState(aktuell) } } Exportfunktion getLocation (Basis: Zeichenfolge): Zeichenfolge { let Pfad = Fenster.Standort.Pfadname wenn (Basis && Pfad.indexOf(Basis) === 0) { Pfad = Pfad.Slice(Basis.Länge) } return (Pfad || '/') + window.location.search + window.location.hash } Die Logik stellt nur sicher, dass die URL existiert. Der Pfad wird direkt aus window.location.pathname durch Abschneiden gewonnen. Er endet mit index.html, kann also nicht mit '/' übereinstimmen, daher funktioniert „index.html über file:// zu öffnen nicht“. Schauen wir uns den Hash-Modus noch einmal an. In HashHistory: exportiere Klasse HashHistory erweitert History { Konstruktor (Router: Router, Basis: ?string, Fallback: Boolean) { ... Schrägstrich sicherstellen () } // dies wird verzögert, bis die App gemountet ist // um zu vermeiden, dass der Hashchange-Listener zu früh ausgelöst wird setupListeners() { window.addEventListener('hashchange', () => { wenn (!ensureSlash()) { zurückkehren } ... }) } getAktuellerStandort() { returniere getHash() } } Funktion EnsureSlash (): Boolesch { const Pfad = getHash() wenn (Pfad.charAt(0) === '/') { returniere wahr } replaceHash('/' + Pfad) return false } Exportfunktion getHash(): Zeichenfolge { const href = fenster.standort.href const index = href.indexOf('#') Rückgabeindex === -1 ? '' : href.slice(index + 1) } Wir können sehen, dass in der Codelogik die Funktion EnsureSlash() oft vorkommt. Wenn auf das Symbol # ein '/' folgt, gibt sie true zurück, andernfalls wird das '/' zwangsweise eingefügt. Daher können wir sehen, dass die URL auch dann die folgende Form annimmt, wenn index.html aus dem Dateisystem geöffnet wird: file:///C:/Benutzer/dist/index.html#/ Der von der Methode getHash() zurückgegebene Pfad ist „/“, der mit der Route der Home-Ansicht übereinstimmt. Wenn Sie daher eine Vue-Einzelseitenanwendung ohne die Hilfe eines Backend-Servers direkt aus dem Dateisystem laden möchten, müssen Sie neben einigen Pfadeinstellungen nach dem Verpacken auch sicherstellen, dass der Vue-Router den Hash-Modus verwendet. Oben sind die Details der beiden Implementierungen des Front-End-Routings aus der Perspektive des Vue-Routers aufgeführt. Weitere Informationen zu den beiden Implementierungen des Vue-Front-End-Routings finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Lösen Sie das Problem der Verwendung von linuxdeployqt zum Verpacken von Qt-Programmen in Ubuntu
1. Regulärer Ausdrucksabgleich ~ für Groß- und Kl...
[LeetCode] 185. Die drei höchsten Gehälter der Ab...
Inhaltsverzeichnis Erster Schritt: Der zweite Sch...
Einfach ausgedrückt bedeutet src „Ich möchte dies...
Inhaltsverzeichnis 1. Einleitung 2. Vorbereitung ...
Bevor Sie diesen Artikel lesen, sollten Sie sich ...
Inhaltsverzeichnis 1. Union-Typ 2. Crossover-Typ ...
Herunterladen: http://dev.mysql.com/downloads/mys...
Wie können Sie also nach der Registrierung eines ...
Von: https://blog.csdn.net/qq_44761243/article/de...
Inhaltsverzeichnis 1. Deduplizierung einrichten 2...
Dieser Artikel veranschaulicht anhand von Beispie...
Die Konvertierung zwischen Zeit, Zeichenfolge und...
Nginx ist ein leistungsstarker, leistungsstarker ...
MVCC MVCC (Multi-Version Concurrency Control) ist...