Sequenz Wenn ich react-router-dom zum Schreiben eines Projekts verwende, finde ich, dass es sehr praktisch zu verwenden ist, aber es ist mühsamer zu warten, weil die Hauptrouten auf verschiedene Komponenten verteilt sind. Daher werden wir uns überlegen, den in react-router-dom bereitgestellten Konfigurationsmodus zum Schreiben unserer Routen zu verwenden. Der Vorteil davon ist, dass wir die Logik an einem Ort konzentrieren und die Routen bequemer konfigurieren können. Projektgalerie 1. Zentralisiertes Routing Wir definieren zunächst die folgenden Daten in /src/router/index.js. Die offizielle Dokumentation des Routings von React bietet einen Fall für die Konfiguration des zentralisierten Routings, der ungefähr so aussieht: Nach dem Routing von Vue wird eine Konfigurationsdatei generiert, die voraussichtlich so aussehen wird //Es ist eine Routing-Konfiguration erforderlich, bei der es sich um ein Array handelt, das Discover von "../pages/Discover" importiert. importiere Djradio aus "../pages/Discover/Djradio" Playlist importieren aus "../pages/Discover/Playlist" Topliste importieren aus "../pages/Discover/Toplist" Freunde aus "../pages/Friends" importieren Importiere Mine aus "../pages/Mine" importiere Page404 von "../pages/Page404" const Routen = [ { Pfad: "/Freunde", Komponente: Freunde }, { Pfad: "/mine", Komponente: Mine }, { Pfad: "/discover", Komponente: Entdecken, Kinder: [ { Pfad: "/discover/djradio", Komponente: Djradio }, { Pfad: "/discover/playlist", Komponente: Playlist }, { Pfad: "/discover/toplist", Komponente: Topliste } ] }, {//Seite 404 Diese Konfiguration muss nach allen Routing-Konfigurationen folgen: Pfad: "*", Komponente: Seite 404 } ] Standardrouten exportieren Wir können die obige Konfiguration verwenden, um eine Route zu generieren. Natürlich ist die obige Konfiguration nur ein einfacher Prozess, und es gibt immer noch Attribute wie „redirect exact“, die nicht geschrieben sind. Beginnen wir mit einem einfachen. 2. Dateiverzeichnis Die obige Konfiguration verwendet einen zentralisierten Routing-Konfigurationsmodus ähnlich wie Vue. Lassen Sie uns also das Strukturverzeichnis meiner aktuellen Demo zeigen. Projektverzeichnisstruktur src/pages Verzeichnisstruktur ├─Entdecken │ │ abc.js │ │ index.js │ │ │ ├─Djradio │ │ │ index.js │ │ │ lf.js │ │ │ │ │ └─gv │ │ index.js │ │ │ ├─Wiedergabeliste │ │ index.js │ │ │ └─Topliste │ index.js │ ├─Unterhaltung │ index.js │ ├─Freunde │ index.js │ xb.js │ ├─Meins │ index.js │ └─Seite 404 index.js Mit diesen Strukturen sind die unter 1. genannten importierten Dateien nicht verwirrend. Als nächstes können wir eine Komponente kapseln und sie CompileRouter nennen. Diese Komponente wird speziell zum Kompilieren von Routen verwendet. 3. CompileRouter erstellen Wir erstellen diese Komponente in src/utils. Ihre Funktion besteht darin, diese Komponente durch die eingehende Routing-Konfiguration zu berechnen. Die Frage ist also, warum wir diese Komponente erstellen müssen? Sehen wir uns an, wie man React-Routing schreibt. React-Routing erfordert eine Basiskomponente namens HashRouter oder BrowserRouter, die einer Eckpfeilerkomponente entspricht. Außerdem wird ein Routing-Rezept benötigt. Diese Komponente kann einen Pfad akzeptieren, der einer Komponente zugeordnet ist. Schreiben wir etwas Pseudocode, um dies zu veranschaulichen. //Grundlegende Routing-Komponenten einführen (um npm i react-router-dom im Projekt zu installieren) importiere {HashRouter als Router,Route} aus „react-router-dom“ Klasse Demo erweitert React.Component { machen(){ //Cornerstone Routing <Router> //Die Routing-Rezeptkomponente stimmt mit der Komponente über den Pfad überein <Routenpfad="/" Komponente={Home}/> <Routenpfad="/mine" component={Mine}/> </Router> } } Dies ist die grundlegende Verwendung. Die Aufgabe unserer CompileRouter-Komponente besteht also darin, die Route wie im obigen Code gezeigt zu generieren, die Route zu generieren und sie dann auf der Komponente anzuzeigen. Nachdem wir die grundlegende Funktion von Compile verstanden haben, beginnen wir mit dem Codieren. Mein CompileRouter ist so konzipiert, dass er Daten akzeptiert. Dabei muss es sich um ein Array handeln, das der Routing-Konfiguration entspricht, genau wie das im Code in 1 gezeigte Array, und das akzeptierte Attribut sind Routen. //Diese Datei kompiliert die Routen durch die Routenkonfiguration. Importieren Sie React von „react“. importiere { Switch, Route } von „react-router-dom“; exportiere Standardklasse CompileRouter erweitert React.Component { Konstruktor() { super() dieser.Zustand = { C: [] } } renderRoute() { let { routes } = this.props; //Routing-Konfiguration für Routen abrufen //1. Routenkomponente über Routen generieren //Sicherstellen, dass Routen ein Array sind // console.log(routes) //render ruft componentDidMount und componentWillUnmount nicht wiederholt auf, wenn (Array.isArray(routes) && routes.length > 0) { // Sicherstellen, dass die eingehenden Routen ein Array sind // Durchlaufen Sie die eingehenden Routen let finalRoutes = routes.map(route => { //Jede Route sieht so aus {path:"xxx",component:"xxx"} //Wenn die Route untergeordnete Knoten hat {path:"xxx",component:"xxx",children:[{path:"xxx"}]} zurück <Routenpfad={route.path} Schlüssel={route.path} render={ // Der Zweck besteht darin, dass wir, wenn die Route verschachtelte Routen hat, die Konfigurationsdaten in den untergeordneten Elementen der Route an diese Komponente übergeben können, sodass die Komponente die verschachtelten Routen kompilieren kann, wenn CompileRouter erneut aufgerufen wird() => <route.component routes={route.children} /> } /> }) dies.setState({ c: finalRoutes }) } anders { throw new Error('Routen müssen ein Array sein und ihre Länge muss größer als 0 sein') } } componentDidMount() { // Stellen Sie sicher, dass renderRoute zum ersten Mal aufgerufen wird, um die Routenkomponente this.renderRoute() zu berechnen } rendern() { lass { c } = dieser.Zustand; zurückkehren ( <Schalter> {C} </Schalter> ) } } Der obige Code wird verwendet, um Routendaten zu verarbeiten und eine solche Komponente zu deklarieren. Ich habe die Rolle jedes Schritts oben mit Kommentaren gekennzeichnet. 4. Verwenden Sie CompileRouter Tatsächlich können wir diese gekapselte Komponente als die Ansichtskomponente <router-view/> in vue-router betrachten. Betrachten wir es zunächst einmal so. Als Nächstes müssen wir die Route der ersten Ebene auf der Seite rendern. In src/app.js React von „react“ importieren importiere { HashRouter als Router, Link } von 'react-router-dom' //Stellen Sie unseren gekapselten CompileRouter vor. Importieren Sie CompileRouter von "./utils/compileRouter". //Importieren Sie die in 1 import routes from "./router" definierten Routing-Konfigurationsdaten. console.log(Routen) Klasse App erweitert React.Component { rendern() { zurückkehren ( <Router> <Link to="/friends">Freunde</Link> | <Link to="/discover">Entdecken</Link> | <Link zu="/mine">Mein</Link> {/*Als Ansichtskomponente von Vue-Router müssen wir die Routing-Konfigurationsdaten übergeben*/} <CompileRouter routes={routes} /> </Router> ) } } Standard-App exportieren Nach dem Schreiben kann die Seite tatsächlich das Level-1-Routing perfekt anzeigen 5. Verschachtelte RoutenverarbeitungWir haben die Route der ersten Ebene oben gerendert und können springen, aber wie gehen wir mit der Route der zweiten Ebene um? Tatsächlich ist es auch sehr einfach. Wir müssen nur die übergeordnete Route der Route der zweiten Ebene finden und weiterhin CompileRouter verwenden. Wir können aus der Konfiguration ersehen, dass die Discover-Route verschachtelte Routen hat, also nehmen wir die Discover-Route als Beispiel. Schauen wir uns zunächst das Strukturdiagramm an Das index.js in der Abbildung ist die Discover-Ansichtskomponente, die auch die übergeordnete Route der verschachtelten Route ist, sodass wir in diesem index.js nur weiterhin CompileRouter verwenden müssen. React von „react“ importieren importiere { Link } von "react-router-dom" importiere CompileRouter von "../../utils/compileRouter" Funktion Discover(Requisiten) { let { routes } = props //Diese Daten werden von den untergeordneten Elementen übergeben, wenn die ComileRouter-Komponente kompiliert wird // console.log(Routen) let links = routes.map(route => { zurückkehren ( <li Schlüssel={Route.Pfad}> <Link zu={route.path}>{route.path}</Link> </li> ) }) zurückkehren ( <Feldsatz> <legend>Entdeckung</legend> <h1>Ich habe festgestellt, dass man nicht einfach mehr heißes Wasser trinken kann</h1> <ul> {links} </ul> {/*Kerncode, Sie können ihn hier erneut verwenden, um die Route durch die untergeordneten Daten zu rendern*/} <CompileRouter routes={routes} /> </Feldsatz> ) } Entdecken.meta = { Titel: "Entdeckung", Symbol: "" } Exportieren Standard Entdecken Wir erinnern uns also daran, dass wir, solange es eine verschachtelte Route gibt, zwei Dinge tun müssen
6. erfordern.KontextWir haben oben eine zentralisierte Routing-Konfiguration implementiert, aber wir werden ein Problem finden Es werden viele Komponenten eingeführt. Tatsächlich werden im Projekt noch mehr eingeführt. Wenn wir sie einzeln einführen, wäre das für uns katastrophal. Daher können wir eine sehr nützliche API verwenden, die von webpack bereitgestellt wird: require.context. Lassen Sie uns zunächst darüber sprechen, wie man sie verwendet. Importieren Sie die Methode require.context automatisch. Die Verwendung dieser Methode kann die mühsame Komponenteneinführung reduzieren und das Verzeichnis tief rekursiv durchsuchen, um Dinge zu tun, die der Import nicht tun kann. Sehen wir uns an, wie man diese Methode verwendet verwenden Sie können Ihren eigenen Kontext mit der Funktion require.context() erstellen.
webpack analysiert während des Builds require.context() in Ihrem Code. Die Syntax lautet wie folgt: erfordern.Kontext( Verzeichnis, (useSubdirectories = true), (regExp = /^\.\/.*$/), (Modus = "Synchronisieren") ); Beispiel: erfordern.context('./test', false, /\.test\.js$/); //(Erstellen) Sie einen Kontext, in dem die Datei aus dem Testverzeichnis stammt und die Anfrage mit „.test.js“ endet. require.context('../', true, /\.stories\.js$/); // (Erstellen) Sie einen Kontext, in dem alle Dateien aus dem übergeordneten Ordner und allen seinen Unterordnern stammen und die Anfrage mit „.stories.js“ endet. APIDie Funktion hat drei Eigenschaften: Auflösung, Schlüssel, ID. „Resolve“ ist eine Funktion, die die Modul-ID zurückgibt, die nach der Auflösung der Anforderung erhalten wurde. lass p = require.context("...",true,"xxx") p.resolve("ein Pfad") keys ist auch eine Funktion, die ein Array zurückgibt, das aus allen Anfragen besteht, die von diesem Kontextmodul verarbeitet werden können (Anmerkung des Übersetzers: siehe Schlüssel im zweiten Codeausschnitt unten). Der Rückgabewert von require.context ist eine Funktion. Wir können den Pfad der Datei an die Funktion übergeben, um eine modulare Komponente zu erhalten. let-Komponenten = require.context('../pages', true, /\.js$/, 'sync') let paths = components.keys() //Adressen aller importierten Dateien abrufen // console.log(paths) let routes = paths.map(path => { let Komponente = Komponenten(Pfad).Standard Pfad = Pfad.substr(1).replace(/\/\w+\.js$/,"") zurückkehren { Weg, Komponente } }) console.log(Routen) ZusammenfassenObwohl es oben viele APIs und Rückgabewerte gibt, werden wir zur Veranschaulichung nur zwei davon verwenden. keys-Methode, die den Pfad aller Module abrufen und ein Array zurückgeben kann let context = require.context("../pages", true, /\.js$/); let paths = context.keys() //Pfade aller Dateien abrufen Alle Module unter dem Pfad abrufen let context = require.context("../pages", true, /\.js$/); let paths = context.keys() //Pfade aller Dateien abrufen let routes = paths.map(path => { //Die importierten Komponenten stapelweise abrufen let component = context(path).default; console.log(Komponente) }) Beherrschen Sie einfach diese beiden, lassen Sie uns weiter verarbeiten 7. Konvertieren flacher Daten in eine Baumstruktur (convertTree-Algorithmus) Ich habe diesen Algorithmus selbst benannt. Zuerst müssen wir verstehen, warum wir Daten in einen Baum konvertieren müssen. //Was ist der Zweck? //Erstelle eine Routing-Konfiguration const routes = [ { Weg: "", Komponente:xxx Kinder:[ { Pfad: „xxx“ Komponente:xxx } ] } ] Tatsächlich sehen die Daten nach der Verwendung der require.context-Verarbeitung jedoch so aus Sie können sehen, dass die Daten völlig flach und ohne Verschachtelung sind. Unser erster Schritt besteht also darin, diese flachen Daten in eine Baumstruktur umzuwandeln, die unseren Erwartungen entspricht. Gehen wir dabei Schritt für Schritt vor. 7.1 Verwenden Sie require.context, um Daten zu vereinfachen Zuerst müssen wir es in die oben gezeigte Struktur verarbeiten. Der Code hat Kommentare und der Schwierigkeitsgrad ist nicht hoch. //erfordern.Kontext() // 1. Ein zu durchsuchendes Verzeichnis, // 2. Ein Flag, das angibt, ob auch die Unterverzeichnisse durchsucht werden sollen. // 3. Ein regulärer Ausdruck, der mit Dateien übereinstimmt. let context = require.context("../pages", true, /\.js$/); let paths = context.keys() //Pfade aller Dateien abrufen let routes = paths.map(path => { //Die importierten Komponenten stapelweise abrufen let component = context(path).default; //Erweiterte Komponentenattribute zur Vereinfachung der Menüdarstellung let meta = component['meta'] || {} //console.log(Pfad) //Der Zweck dieses regulären Ausdrucks //Da die Adresse ./Discover/Djradio/index.js lautet, kann dieser Adresstyp nicht direkt verwendet werden und muss daher verarbeitet werden //1. Entfernen Sie dann das erste "." und das Ergebnis ist /Discover/Djradio/index.js //2. Nach der Verarbeitung kann es immer noch nicht direkt verwendet werden, da wir /Discover/Djradio erwarten. Daher verwenden wir reguläre Ausdrücke, um index.js zu beenden. //3. Es ist möglich, dass der nachfolgende Pfad kein Ordner ist und das Ergebnis /Discover/abc.js ist. Der Suffixname kann im Pfadattribut der Routing-Konfiguration nicht verwendet werden. Daher wird der Suffixname .js durch den regulären Ausdruck path = path.substr(1).replace(/(\/index\.js|\.js)$/, "") ersetzt. // console.log(Pfad) zurückkehren { Weg, Komponente, Meta } }) 7.2 Implementierung des convertTree-Algorithmus Nach der Verarbeitung der obigen Daten kapseln wir eine Methode speziell für die Verarbeitung abgeflachter Daten in Baumdaten. Die zeitliche Komplexität des Algorithmus beträgt O(n^2) Funktion convertTree(Routen) { lass treeArr = []; //1. Verarbeiten Sie die Daten und verarbeiten Sie die ID und das übergeordnete Element jedes Datenelements (allgemein bekannt als „Wohin geht Papa?“). Routen.fürJedes(Route => { let comparePaths = route.path.substr(1).split("/") // console.log(Pfade vergleichen) wenn (comparePaths.length === 1) { // Zeigt an, dass es sich um einen Stammknoten handelt. Der Stammknoten muss keine parent_id hinzufügen route.id = comparePaths.join("") } anders { //Beschreibung hat einen übergeordneten Knoten//Verarbeite zuerst seine eigene ID route.id = comparePaths.join(""); //comparePaths, außer dass das letzte Element parent_id ist VergleichePfade.pop() route.parent_id = comparePaths.join("") } }) //2. Alle Daten haben die ID des übergeordneten Knotens gefunden. Als nächstes folgt die eigentliche Suche nach dem übergeordneten Knoten: routes.forEach(route => { //Beurteilen Sie, ob die aktuelle Route eine parent_id hat wenn (route.übergeordnete_id) { //Die Route mit dem übergeordneten Knoten //id===parent_id ist der übergeordnete Knoten der aktuellen Route let target = routes.find(v => v.id === route.parent_id); //Beurteilen, ob der übergeordnete Knoten das Attribut „children“ hat, if (!target.children) { Ziel.Kinder = [] } Ziel.Kinder.Push(Route) } anders { treeArr.push(Route) } }) Rückgabewert treeArr } Nach der obigen Verarbeitung können wir die Baumstruktur erhalten. Als nächstes müssen wir nur noch die Daten exportieren, in die App importieren und an die CompileRouter-Komponente übergeben. 7.3 Zukünftig zu beachtende PunkteIn Zukunft müssen Sie nur noch Dateien in Seiten erstellen, um Routen automatisch zu verarbeiten und zu kompilieren. Vergessen Sie jedoch bei verschachtelten Routen nicht, die Komponente CompileRouter zur Routenkomponente hinzuzufügen. Hier sind die Highlights:
8. Erweitern statischer Eigenschaften Der von uns erstellte Effekt ist vorhanden, aber wenn wir ihn zum Rendern des Menüs verwenden, tritt ein Problem auf. Es gibt keinen Inhalt zum Rendern des Menüs, daher können wir das statische Attribut meta (oder anderes) der Komponente erweitern und dann einige kleine Änderungen an unserem automatischen Kompilierungscode vornehmen. Komponenten Vollständiger Code der Automatisierungsverarbeitungslogik//erfordern.Kontext() // 1. Ein zu durchsuchendes Verzeichnis, // 2. Ein Flag, das angibt, ob auch die Unterverzeichnisse durchsucht werden sollen. // 3. Ein regulärer Ausdruck, der mit Dateien übereinstimmt. let context = require.context("../pages", true, /\.js$/); let paths = context.keys() //Pfade aller Dateien abrufen let routes = paths.map(path => { //Die importierten Komponenten stapelweise abrufen let component = context(path).default; //Erweiterte Komponentenattribute zur Vereinfachung der Menüdarstellung let meta = component['meta'] || {} //console.log(Pfad) //Der Zweck dieses regulären Ausdrucks //Da die Adresse ./Discover/Djradio/index.js lautet, kann dieser Adresstyp nicht direkt verwendet werden und muss daher verarbeitet werden //1. Entfernen Sie dann das erste "." und das Ergebnis ist /Discover/Djradio/index.js //2. Nach der Verarbeitung kann es immer noch nicht direkt verwendet werden, da wir /Discover/Djradio erwarten. Daher verwenden wir reguläre Ausdrücke, um index.js zu beenden. //3. Es ist möglich, dass der nachfolgende Pfad kein Ordner ist und das Ergebnis /Discover/abc.js ist. Der Suffixname kann im Pfadattribut der Routing-Konfiguration nicht verwendet werden. Daher wird der Suffixname .js durch den regulären Ausdruck path = path.substr(1).replace(/(\/index\.js|\.js)$/, "") ersetzt. // console.log(Pfad) zurückkehren { Weg, Komponente, Meta } }) //Diese Art von Daten sind flache Daten und entsprechen nicht unseren Routing-Regeln. //Wir müssen einen Algorithmus erstellen, um die Zeitkomplexität so weit wie möglich auf o(n) zu reduzieren. //Kapseln Sie einen convertTree-Algorithmus mit einer Zeitkomplexität von o(n^2). // console.log(Routen) //Ausweis //übergeordnete_ID Funktion convertTree(Routen) { lass treeArr = []; //1. Verarbeiten Sie die Daten und verarbeiten Sie die ID und das übergeordnete Element jedes Datenelements (allgemein bekannt als „Wohin geht Papa?“). Routen.fürJedes(Route => { let comparePaths = route.path.substr(1).split("/") // console.log(Pfade vergleichen) wenn (comparePaths.length === 1) { // Zeigt an, dass es sich um einen Stammknoten handelt. Der Stammknoten muss keine parent_id hinzufügen route.id = comparePaths.join("") } anders { //Beschreibung hat einen übergeordneten Knoten//Verarbeite zuerst seine eigene ID route.id = comparePaths.join(""); //comparePaths, außer dass das letzte Element parent_id ist VergleichePfade.pop() route.parent_id = comparePaths.join("") } }) //2. Alle Daten haben die ID des übergeordneten Knotens gefunden. Als nächstes folgt die eigentliche Suche nach dem übergeordneten Knoten: routes.forEach(route => { //Beurteilen Sie, ob die aktuelle Route eine parent_id hat wenn (route.übergeordnete_id) { //Die Route mit dem übergeordneten Knoten //id===parent_id ist der übergeordnete Knoten der aktuellen Route let target = routes.find(v => v.id === route.parent_id); //Beurteilen, ob der übergeordnete Knoten das Attribut „children“ hat, if (!target.children) { Ziel.Kinder = [] } Ziel.Kinder.Push(Route) } anders { treeArr.push(Route) } }) Rückgabewert treeArr } exportiere standardmäßig convertTree(Routen) //Ein Modul abrufen // console.log(p("./Discover/index.js").default) //Was ist der Zweck? //Erstelle eine Routing-Konfiguration // const routes = [ // { // Weg: "", // Komponente, // Kinder:[ // {Pfadkomponente} // ] // } // ] Abschließende Gedanken Tatsächlich kann die obige Verarbeitung im Projekt nicht als Anwendungsebene verwendet werden, hauptsächlich weil die CompileRouter-Verarbeitung nicht detailliert genug ist. In der nächsten Ausgabe werde ich einen speziellen Artikel darüber schreiben, wie CompileRouter für die Authentifizierung und andere Anwendungen im Projekt verwendet wird. Dies ist das Ende dieses Artikels über die Implementierung des automatisierten Routings in React. Weitere Informationen zum automatisierten Routing in React 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:
|
<<: So implementieren Sie die Paging-Funktion des MyBatis-Interceptors
>>: Detaillierte Erklärung zum Erstellen eines FTP-Servers unter Ubuntu (Erfolg garantiert)
In diesem Artikel wird der spezifische Code für V...
1. Einführung in Docker 1.1 Virtualisierung 1.1.1...
Kriegspaket vorbereiten 1. Bereiten Sie das vorha...
1. Offizielle Website-Adresse Auf der offiziellen...
Der Zweck der Verwendung von HTML zum Markieren v...
Zusammenfassen Dieser Artikel endet hier. Ich hof...
Bei einem unserer Webprojekte ist aufgrund der Zu...
1. Online-Installation Derzeit habe ich nur die O...
Vorwort Jeder sollte mit der Watch-API in vue2 ve...
Inhaltsverzeichnis Problembeschreibung Ursachenan...
Alles ist eine Datei! UNIX hat es bereits gesagt....
Würmer replizieren sich, wie der Name schon sagt,...
Inhaltsverzeichnis Vorwort 1. Anwendungsbeispiele...
1. Laden Sie zunächst die entsprechende Datenbank...
Anwendungsszenario: Es ist notwendig, die Anzahl ...