前言
React 小白,错误之处,请指明。
本文章借鉴多篇 React 路由的写法,抄袭在所难免。
主要是记录个人的成长历程。
如果帮到您了,不妨点赞支持。
正文
需求解析
- router.config
- 通过 Router.config 配置路由,方便管理。
- 前置路由组件(路由守卫)
- 对部分路由页面进行鉴权。
- App、Router 改造
- App 对整个窗口进行针对性跳转,例如登陆页面和 Admin 页面
- Router 对部分页面进行跳转,例如登陆进入 Admin 后的页面
- Menu 变化
- 菜单跟随路由的变化而改变
安装react-router-dom
。
npm install react-router-dom
准备工作
- 在
/src
目录下创建router
文件夹 - 在
/src/router
目录下创建FrontendAuth.jsx
、index.jsx
、router.config.js
写入代码
-
打开
router.config.js
,// 我们定义一个项为: { name?: String, path: String, title?: String, component?: any, children?: Object, auth?: Boolean }
解析:
name -> 路由名
path -> 路由地址(必填)
title -> 浏览器标签标题
component -> 路由名
children -> 子路由-
router.config.js
示例:
// router.config.js import Login from "../pages/User/Login"; import Admin from "../pages/Admin/index"; import ErrorPage from "../pages/errors/404"; import PageOne from "../pages/Test/PageOne"; import PageTwo from "../pages/Test/PageTwo"; export const routerConfig = [ { name: "login", path: "/login", component: Login, title: "用户登陆", }, { name: "404", path: "/404", component: ErrorPage }, { name: "index", path: "/index", component: Admin, auth: true, children: [ { name: "pageOne", path: "/pageOne", component: PageOne, auth: true, }, { name: "pageTwo", path: "/pageTwo", component: PageTwo, auth: true, }, ], }, ];
-
-
写
FrontendAuth.jsx
路由前置组件- 基本思路:
- 如果请求地址在 router.config 中,通过
<Route ... />;
进行跳转 - 如果 router.config 不存在该地址或者该地址未通过鉴权,则通过
<Redirect ... />
进行重定向
- 如果请求地址在 router.config 中,通过
- 示例代码:
// FrontendAuth.jsx import React from "react"; import { Route, Redirect } from "react-router-dom"; // 用于鉴定路由地址是否在配置中。 const findRouterNode = (config, path) => { let item = null; config.map((e) => { if (item == null) { if (e.path === path) { item = e; } else if (e.children) { item = findRouterNode(e.children, path); } } }); return item; }; export class FrontendAuth extends React.Component { render() { const { location, config } = this.props; const { pathname } = location; const isLogin = true; //localStorage.getItem("__config_center_token"); // 如果该路由不用进行权限校验,登录状态下登陆页除外 // 因为登陆后,无法跳转到登陆页 // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由\ const targetRouterConfig = findRouterNode(config, pathname); if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) { const { component } = targetRouterConfig; return <Route exact path={pathname} component={component} />; } if (isLogin) { // 如果是登陆状态,想要跳转到登陆,重定向到主页 if (pathname === "/login") { return <Redirect to="/" />; } else { // 如果路由合法,就跳转到相应的路由 if (targetRouterConfig) { document.title = targetRouterConfig.name; return ( <Route path={pathname} component={targetRouterConfig.component} /> ); } else { // 如果路由不合法,重定向到 404 页面 return <Redirect to="/404" />; } } } else { // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆 if (targetRouterConfig && targetRouterConfig.auth) { return <Redirect to="/login" />; } else { // 非登陆状态下,路由不合法时,重定向至 404 return <Redirect to="/404" />; } } } }
- 基本思路:
-
/src/router/index.jsx
二级路由- 基本思路:
- 将
router.config
通过FrontendAuth
的config
属性给前置路由组件。 - 将页面的路由信息通过
Menu
的location
属性传输给菜单组件 - 注意:后面
App.jsx
的写法。 - 注意:后面
App.jsx
的写法。 - 注意:后面
App.jsx
的写法。
- 将
- 示例代码:
// index.jsx import React, { Component } from "react"; import { HashRouter, Switch, Route, Link } from "react-router-dom"; import { FrontendAuth } from "./FrontendAuth"; import { routerConfig } from "./router.config"; import Menu from "../components/menu/menu"; export class Router extends Component { constructor(props) { super(props); } render() { return ( <div> <Menu location={this.props.location} /> <HashRouter> <Switch> <FrontendAuth config={routerConfig} /> </Switch> </HashRouter> </div> ); } }
- 基本思路:
-
/src/App.jsx
改造- 示例代码:
import React, { useState } from "react"; import { Router } from "./router"; import { HashRouter, Switch, Route, Link } from "react-router-dom"; import Login from "./pages/User/Login"; export default class App extends React.Component { render() { return ( <div className="bg-pink-400 text-white h-screen w-screen"> <HashRouter> <Switch> <Route path="/login" component={Login} /> <Router /> </Switch> </HashRouter> </div> ); } }
总结
有误请指出。谢谢指导
- 因为业务的需求,在一部分页面中无需 Menu 组件,所以通过嵌
HashRouter
的方式实现路由的跳转。 - 路由的跳转信息经过测试只能在
HashRouter
内拿到。(我也不知道对不对哈,没有用其他的方式) - 因为 Menu 属于组件,所以无需包含
Switch
内,否则会被调用多次。(猜测,因为 switch 进行路由匹配,所以多次执行了,导致 Menu 多次执行。 - 这个教程也是本人一知半解写的。后续可能会跟进修改。