Router6
- 相比于Router5,Router6由
<Routes/>
取代了<Swith/>
,Route组件的component
属性替换为element
属性 - 使用
<Navigate/>
替代Router5的<Redirect/>
1. 路由拆分
- 为了项目结构的清晰,一般会把路由组件单独的抽取到一个独立的文件里,最后在根组件引入
import React, { Component } from "react";
import MyRouters from "./Router/MyRouters";
import { BrowserRouter } from "react-router-dom";
export default class App extends Component {
render() {
return (
<BrowserRouter>
<MyRouters />
</BrowserRouter>
);
}
}
import { Routes, Route } from "react-router-dom";
import Login from "../components/Login/Login";
import Count from "../components/Count/Count";
export default function MyRouters() {
return (
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/count/*" element={<Count />} />
</Routes>
);
}
/* */
2. 嵌套路由
- 当存在嵌套路由是,要想子路由的组件可以显示,必须在父组件里预留”占位“的路由容器:
<Outlet/>
,由<Outlet/>
决定子路由所展示的组件显示在父路由展示的组件的哪个位置 - 如果子路由所映射的组件数量少于父路由所预留的路由容器数量,那么子路由的组件将会被渲染多次
嵌套路由的写法①:绝对路径
import { Routes, Route } from "react-router-dom";
import Login from "../components/Login/Login";
import Count from "../components/Count/Count";
import Loading from "../components/Loading/Loading";
import User from "../components/User/User";
export default function MyRouters() {
return (
<Routes>
<Route path="/login" element={<Login />}>
<Route path="/login/user" element={<User />} />
</Route>
<Route path="/count/*" element={<Count />} />
<Route index element={<Loading />} />
</Routes>
);
}
/* */
嵌套路由的写法②:相对路径
import { Routes, Route } from "react-router-dom";
import Login from "../components/Login/Login";
import Count from "../components/Count/Count";
import Loading from "../components/Loading/Loading";
import User from "../components/User/User";
export default function MyRouters() {
return (
<Routes>
<Route path="/login" element={<Login />}>
<Route path="user" element={<User />} />
</Route>
<Route path="/count/*" element={<Count />} />
</Routes>
);
}
/* */
<Route/>
的index属性
import { Routes, Route } from "react-router-dom";
import Login from "../components/Login/Login";
import Count from "../components/Count/Count";
import Loading from "../components/Loading/Loading";
import User from "../components/User/User";
export default function MyRouters() {
return (
<Routes>
<Route path="/login" element={<Login />}>
<Route path="user" element={<User />} />
<Route index element={<Loading />} />
</Route>
<Route path="/count/*" element={<Count />} />
</Routes>
);
}
/* */
- index路由和其他路由不同的地方是它没有path属性,它和父路由共享同一个路径
- index用于嵌套路由,仅匹配父路径时,设置渲染的组件
- 解决当嵌套路由有多个子路由,但本身无法确认渲染哪个子路由的时候,可以增加index属性来指定默认路由(个人理解:可以用于根路径下系统首页的欢迎页)
- 相当于在输入父级路由后,同时渲染父级路由组件和子路由组件,前提是父组件留了组件容器
- path=“*”,代表匹配所有路径,一般放在路由组件的最后一行,当所有的路径都匹配不上时,走这一个路由
<Route/>
的element属性
- element可以防止任何一个内置或者自定义组件,比如放置一个
<Navigate/>
<Route/>
的caseSensittive属性
- 用于指定匹配时是否区分大小写
<Route/>
可以嵌套使用,且可配合useRoutes()配置路由表,但需要通过<outLet/>
3. 路由表
- 通过使用
useRoutes()
这个hook,帮助生成路由表,开发者不需要去手动的写<Route/>
标签,只需要指定<Route/>
标签内部的path
和element
属性的值即可
import { Routes, Route, Navigate } from "react-router-dom";
import {lazy, Suspense} from 'react'
// import Login from "../components/Login/Login";
// import Count from "../components/Count/Count";
import Loading from "../components/Loading/Loading";
import User from "../components/User/User";
import Hello from "../components/Hello/Hello";
import List from "../components/List";
const Login = lazy(()=> import('../components/Login/Login') )
const Count = lazy(()=> import('../components/Count/Count'))
//const Hello = lazy(()=> import('../components/Hello/Hello'))
export default function MyRouters() {
return (
<Suspense fallback={<Loading/>}>
<Routes>
<Route path="/login" element={<Login />}>
<Route path="user" element={<User />} />
<Route index element={<Loading />} />
</Route>
<Route path="/count/*" element={<Count />} />
<Route path="/list/" element={<List />} />
{/* <Route path="/hello/:id" element={<Hello />} /> */}
<Route path="/hello" element={<Hello />} />
<Route path="/count/world" element={<Navigate to="/count/hello" />} />
</Routes>
</Suspense>
);
}
- 被替换成
import { lazy } from "react";
import Hello from "../components/Hello/Hello";
import { Navigate } from "react-router-dom";
import List from "../components/List";
import User from "../components/User/User";
const Login = lazy(() => import("../components/Login/Login"));
const Count = lazy(() => import("../components/Count/Count"));
const element = [
{
path: "/login",
element: <Login />,
children: [
{
path: "user",
element: <User />,
},
],
},
{
path: "/count",
element: <Count />,
},
{
path: "/list",
element: <List />,
},
{
path: "/hello",
element: <Hello />,
},
{
path: "/world",
element: <Navigate to="/count/hello" />,
},
];
export default element;
- 路由表不建议直接默认暴露,这样外部引用可能会识别成一个对象,而不是一个数组,推荐定义成变量,再暴露给外部
<OutLet>
是针对函数式组件的组件容器(Vue叫插槽),对标类式组件的this.props.children
<NavLink/>
组件的to属性有3种写法,分别是
<NavLink to="/hello">Hello</NavLink> | 绝对路径 | 无论当前路径是啥,点击当前连接会在根路径后面拼/hello |
---|---|---|
<NavLink to="./hello">Hello</NavLink> | 相对路径 | 相对于当前路径,点击当前链接,会在当前路径后面拼/hello |
<NavLink to="hello">Hello</NavLink> | 相对路径 | 相对于当前路径,点击当前链接,会在当前路径后面拼/hello |
-
2和3是一个意思,一般都使用3
-
<NavLink/>
相对于<Link/>
具有高亮的特性,如果存在多级路由,从父级路由跳转到子级路由,子级路由和父级路由组件都会具有高亮的效果,如果不希望父级路由高亮,就在父级的<NavLink/>
上加一个end属性
<NavLink to="/hello" end >Hello</NavLink>