10 Minuten, um das Single-Page-Anwendungsrouting des WeChat-Applets gründlich zu verstehen

10 Minuten, um das Single-Page-Anwendungsrouting des WeChat-Applets gründlich zu verstehen

Merkmale einer Single-Page-Anwendung

„Annahme:“ Auf einer Webseite gibt es eine Schaltfläche, über die man durch Anklicken zu anderen Seiten der Site springen kann.

„Mehrseitige Anwendung“: Klicken Sie auf die Schaltfläche, um eine HTML-Ressource neu zu laden und die gesamte Seite zu aktualisieren.

„Einzelseitenanwendung“: Wenn Sie auf eine Schaltfläche klicken, erfolgt keine neue HTML-Anforderung, sondern nur eine teilweise Aktualisierung. Dadurch kann ein nahezu natives und reibungsloses Erlebnis geschaffen werden.

Warum können SPA-Single-Page-Anwendungen nahezu ohne Aktualisierung auskommen? Wegen seiner SP – Single-Page. Beim ersten Aufruf der Anwendung wird lediglich die HTML-Seite und deren öffentliche statische Ressourcen zurückgegeben. Die nachfolgenden sogenannten „Sprünge“ holen sich nicht mehr die HTML-Datei vom Server, sondern sind lediglich DOM-Ersetzungsoperationen, die simuliert werden.

Wie erfasst js also den Zeitpunkt des Komponentenwechsels und ändert die Browser-URL ohne Aktualisierung? Verlassen Sie sich auf Hash und HTML5History.

Hash-Routing

Besonderheit

  • Ähnlich wie www.xiaoming.html#bar handelt es sich um eine Hash-Route. Wenn sich der Hash-Wert nach # ändert, werden keine Daten vom Server angefordert. Die Änderung der URL kann über das Hashchange-Ereignis überwacht werden, um DOM-Operationen durchzuführen, die einen Seitensprung simulieren.
  • Keine Serverkooperation erforderlich
  • Nicht SEO-freundlich

Prinzip

Hash

HTML5History-Routing

Besonderheit

  1. Der Verlaufsmodus ist eine neue Funktion von HTML5. Er ist intuitiver als Hash-Routing und sieht folgendermaßen aus: www.xiaoming.html/bar. Um einen Seitensprung zu simulieren, wird history.pushState(state, title, url) verwendet, um die Browserroute zu aktualisieren. Wenn sich die Route ändert, wird das Popstate-Ereignis abgehört, um den DOM zu betreiben.
  2. Für die Umleitung ist eine Backend-Kooperation erforderlich
  3. Relativ SEO-freundlich

Prinzip

HTML5Geschichte

Interpretation des Vue-Router-Quellcodes

Nehmen wir als Beispiel den Router vue-router von Vue und werfen wir einen Blick auf seinen Quellcode.

Tipps: Da der Schwerpunkt dieses Artikels auf der Erläuterung der beiden Modi der Einzelseitenweiterleitung liegt, werden nachfolgend nur einige Schlüsselcodes aufgeführt, die hauptsächlich Folgendes erklären:

  1. Plugin registrieren
  2. Der Konstruktor von VueRouter unterscheidet Routing-Modi
  3. Komponenten global registrieren
  4. Push- und Listen-Methoden für den Hash-/HTML5History-Modus
  5. Methode „transitionTo“

Plugin registrieren

Zunächst müssen Sie als Plug-In bewusst eine Installationsmethode für die Verwendung durch Vue bereitstellen.

In der Datei install.js des Quellcodes wird die Installationsmethode zum Registrieren und Installieren des Plug-Ins definiert, die Methode wird in die Hook-Funktion jeder Komponente eingemischt und die Route wird initialisiert, wenn der Hook beforeCreate ausgeführt wird:

Vue.mixin({
 vorErstellen () {
 wenn (isDef(this.$options.router)) {
 this._routerRoot = dies
 dieser._router = dieser.$options.router
 dies._router.init(dies)
 Vue.util.defineReactive(dies, '_route', dies._router.history.current)
 } anders {
 dies._routerRoot = (dieses.$parent && dies.$parent._routerRoot) || dies
 }
 registerInstance(dies, dies)
 },
 // Im gesamten Text wird ... verwendet, um ausgelassene Methoden anzuzeigen ...
});

Unterscheidungsmodus

Dann finden wir die Basisklasse VueRouter des gesamten Plug-Ins aus index.js. Es ist nicht schwer zu erkennen, dass sie je nach Modus unterschiedliche Routing-Instanzen im Konstruktor verwendet.

...
importiere {install} von './install';
importiere {HashHistory} aus './history/hash';
importiere {HTML5History} aus './history/html5';
...
exportiere Standardklasse VueRouter {
 statische Installation: () => void;
 Konstruktor (Optionen: RouterOptions = {}) {
 wenn (dieser.fallback) {
 Modus = "Hash"
 }
 wenn (!imBrowser) {
 Modus = "abstrakt"
 }
 this.mode = Modus
  
 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}`)
 }
 }
 }
}

Registrieren Sie die Router-Link-Komponente global

An dieser Stelle können wir fragen: Wo werden bei der Verwendung von Vue-Router die allgemeinen <router-link/> und <router-view/> eingeführt?

Zurück zur Datei install.js. Sie importiert und registriert die Komponenten „Router-View“ und „Router-Link“ global:

Importiere Ansicht aus „./components/view“.
Link aus „./components/link“ importieren;
...
Vue.component('RouterView', Ansicht);
Vue.component('RouterLink', Link);

In ./components/link.js ist das Klickereignis standardmäßig an die Komponente <router-link/> gebunden, und der Klick löst die Handlermethode aus, um den entsprechenden Routingvorgang auszuführen.

const handler = e => {
 wenn (guardEvent(e)) {
 wenn (dies.ersetzen) {
 router.replace(Standort, noop)
 } anders {
 router.push(Standort, noop)
 }
 }
};

Wie eingangs erwähnt, initialisiert der VueRouter-Konstruktor für unterschiedliche Modi unterschiedliche Modi von History-Instanzen, sodass auch die Methoden von router.replace und router.push unterschiedlich sind. Als Nächstes werden wir den Quellcode dieser beiden Modi herunterladen.

Hash-Modus

In der Datei history/hash.js ist die Klasse HashHistory definiert, die von der Basisklasse History in history/base.js erbt.
Die Push-Methode ist in ihrem Prototyp definiert: In einer Browserumgebung, die den HTML5History-Modus unterstützt (supportsPushState ist true), wird history.pushState aufgerufen, um die Browseradresse zu ändern; in anderen Browserumgebungen wird location.hash = path direkt verwendet, um die neue Hash-Adresse zu ersetzen.

Tatsächlich hatte ich einige Zweifel, als ich das zum ersten Mal las. Da es sich bereits im Hash-Modus befindet, warum müssen wir dann den Support von PushState beurteilen? Es stellt sich heraus, dass history.pushState zur Unterstützung von scrollBehavior einen Schlüsselparameter übergeben kann, sodass jeder URL-Verlauf einen Schlüssel hat und der Schlüssel zum Speichern der Standortinformationen jeder Route verwendet wird.

Gleichzeitig ist die an den Prototyp gebundene Methode „setupListeners“ dafür verantwortlich, auf den Zeitpunkt von Hash-Änderungen zu achten: In Browserumgebungen, die den HTML5History-Modus unterstützen, achtet sie auf Popstate-Ereignisse, in anderen Browsern auf Hash-Änderungen. Nach der Überwachung der Änderungen wird die Methode handleRoutingEvent ausgelöst, die TransitionTo-Sprunglogik der übergeordneten Klasse aufgerufen und der DOM-Ersetzungsvorgang ausgeführt.

importiere { pushState, replaceState, supportsPushState } von '../util/push-state'
...
exportiere Klasse HashHistory erweitert History {
 setupListeners() {
 ...
 const handleRoutingEvent = () => {
 const current = dies.aktuell
 wenn (!ensureSlash()) {
  zurückkehren
 }
 // Die Sprungmethode unter der übergeordneten Klasse History wird von transitionTo aufgerufen. Der Pfad wird nach dem Sprung gehasht this.transitionTo(getHash(), route => {
  if (unterstütztScroll) {
  handleScroll(dieser.Router, Route, aktuell, wahr)
  }
  wenn (!supportsPushState) {
  replaceHash(route.vollständigerPfad)
  }
 })
 }
 const eventType = unterstütztPushState ? 'popstate' : 'hashchange'
 Fenster.addEventListener(
 Ereignistyp,
 RoutingEvent-Handle
 )
 dies.listeners.push(() => {
 window.removeEventListener(Ereignistyp, Routing-Ereignis behandeln)
 })
 }
 
 push (Standort: Rohstandort, bei Abschluss?: Funktion, bei Abbruch?: Funktion) {
 const { current: fromRoute } = dies
 dies.transitionTo(
 Standort,
 Route => {
 pushHash(route.vollständigerPfad)
 handleScroll(dieser.Router, Route, vonRoute, false)
 beiAbgeschlossen und beiAbgeschlossen(Route)
 },
 beiAbbruch
 )
 }
}
...

// Den eingehenden Pfad in eine gehashte URL verarbeiten
Funktion getUrl (Pfad) {
 const href = fenster.standort.href
 const i = href.indexOf('#')
 const base = i >= 0 ? href.slice(0, i) : href
 gibt `${base}#${path}` zurück
}
...

// Hash ersetzen
Funktion pushHash (Pfad) {
 if (unterstütztPushState) {
 pushState(getUrl(Pfad))
 } anders {
 window.location.hash = Pfad
 }
}

//Methode in der Datei util/push-state.js export const supportsPushState =
 imBrowser &&
 (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 Typ von window.history.pushState zurück === 'Funktion'
 })()

HTML5History-Modus

Ebenso ist die Klasse HTML5History in history/html5.js definiert.

Definieren Sie die Push-Prototypmethode und rufen Sie history.pusheState auf, um den Browserpfad zu ändern.

Gleichzeitig überwacht die SetupListeners-Methode des Prototyps das Popstate-Ereignis und nimmt rechtzeitig DOM-Ersetzungen vor.

importiere {pushState, replaceState, supportsPushState} aus '../util/push-state';
...
Exportklasse HTML5History erweitert History {

 setupListeners() {

 const handleRoutingEvent = () => {
 const aktuell = dies.aktuell;
 const location = getLocation(diese.base);
 wenn (dieser.aktuelle === START && Standort === dieser._startStandort) {
 zurückkehren
 }

 dies.transitionTo(Standort, Route => {
 if (unterstütztScroll) {
 handleScroll(Router, Route, aktuell, wahr)
 }
 })
 }
 window.addEventListener('popstate', handleRoutingEvent)
 dies.listeners.push(() => {
 window.removeEventListener('popstate', handleRoutingEvent)
 })
 }
 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)
 }
}

...

//Methode in util/push-state.js Dateiexportfunktion pushState (URL?: Zeichenfolge, Ersetzen?: Boolescher Wert) {
 saveScrollPosition()
 const history = fenster.history
 versuchen {
 wenn (ersetzen) {
 const stateCopy = erweitern({}, Verlauf.Zustand)
 stateCopy.key = getStateKey()
 history.replaceState(Staatskopie, '', URL)
 } anders {
 history.pushState({ Schlüssel: setStateKey(genStateKey()) }, '', URL)
 }
 } fangen (e) {
 window.location[ersetzen? 'ersetzen': 'zuweisen'](URL)
 }
}

transitionTo behandelt die Routenänderungslogik

Die beiden oben genannten Routing-Modi lösen beide this.transitionTo beim Abhören aus. Was ist das? Es handelt sich eigentlich um eine Prototypmethode, die in der Basisklasse history/base.js definiert ist und zur Handhabung der Routing-Änderungslogik verwendet wird.

Verwenden Sie zunächst const route = this.router.match(location, this.current), um den übergebenen Wert mit dem aktuellen Wert zu vergleichen und das entsprechende Routenobjekt zurückzugeben. Bestimmen Sie dann, ob die neue Route mit der aktuellen Route identisch ist. Wenn ja, geben Sie sie direkt zurück. Wenn nicht, führen Sie den Rückruf in this.confirmTransition aus, um das Routenobjekt zu aktualisieren und das ansichtsbezogene DOM zu ersetzen.

Exportklasse Verlauf {
 ...
 Übergang zu (
 Standort: RawLocation,
 onComplete?: Funktion,
 onAbort?: Funktion
 ) {
 const route = dieser.router.match(Standort, dieser.aktuell)
 dies.confirmTransition(
 Route,
 () => {
 const prev = dies.aktuell
 dies.updateRoute(route)
 beiAbgeschlossen und beiAbgeschlossen(Route)
 dies.ensureURL()
 dies.router.afterHooks.forEach(hook => {
  Hook und Hook (Route, vorherige)
 })

 wenn (!diese.bereit) {
  dies.ready = true
  dies.readyCbs.forEach(cb => {
  cb(Route)
  })
 }
 },
 err => {
 if (beiAbbruch) {
  beiAbbruch(fehler)
 }
 wenn (err && !this.ready) {
  dies.bereit = wahr
  // https://github.com/vuejs/vue-router/issues/3225
  wenn (!isRouterError(err, NavigationFailureType.redirected)) {
  dies.readyErrorCbs.forEach(cb => {
  cb(err)
  })
  } anders {
  dies.readyCbs.forEach(cb => {
  cb(Route)
  })
  }
 }
 }
 )
 }
 ...
}

endlich

Nun, das Obige ist ein kleiner Einblick in das Routing einzelner Seiten. Ich hoffe, wir können es schaffen, von den ersten Schritten zu „niemals aufgeben“ zu kommen~~

Damit ist der Artikel abgeschlossen, in dem erklärt wird, wie man das Routing von Einzelseitenanwendungen im WeChat Mini-Programm in 10 Minuten gründlich versteht. Weitere relevante Inhalte zum Routing von Einzelseitenanwendungen im Mini-Programm 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:
  • Android-Entwicklung WeChat Applet Routing Jump-Methode
  • Lernhinweise zum WeChat-Applet: Seitenkonfiguration und -routing
  • Routing-Dateien und Routing-Methoden zur Miniprogramm-Kapselung (5 vollständige Analysen)
  • Problem bei der Routing-Umschaltung und Seitenumleitung bei der Entwicklung von WeChat-Applets
  • Beispielanalyse für WeChat-Applet-Routing-Sprung in zwei Richtungen

<<:  Grafisches Tutorial zur Installation der dekomprimierten Version von mysql5.7.14

>>:  Mysql behält den vorhandenen Inhalt bei und fügt später Inhalte hinzu

Artikel empfehlen

Analyse der Gründe, warum das MySQL-Indexsystem den B + -Baum verwendet

Inhaltsverzeichnis 1. Was ist ein Index? 2. Warum...

MySQL-Protokolleinstellungen und Anzeigemethoden

MySQL verfügt über die folgenden Protokolle: Fehl...

js, um den Popup-Effekt zu erzielen

In diesem Artikelbeispiel wird der spezifische Co...

Tutorial zur HTML-Tabellenauszeichnung (1): Erstellen einer Tabelle

<br />Dies ist eine Reihe von Tutorials, die...

Versuchen Sie Docker+Nginx, um die Single-Page-Anwendungsmethode bereitzustellen

Von der Entwicklung bis zur Bereitstellung: Mache...

Details zur MySQL-Transaktionsisolationsebene

serializable Serialisierung (kein Problem) Transa...

Detaillierte Schritte zur Installation und Konfiguration von MySQL 5.7

1. MySQL herunterladen 1. Melden Sie sich auf der...

So erstellen Sie eine PHP+Nginx+Swoole+MySQL+Redis-Umgebung mit Docker

Betriebssystem: Alibaba Cloud ESC-Instanz centos7...