React路由可以实现页面间的切换。
传送门:英文文档
中文教程:
https://www.reactrouter.cn/docs/getting-started/tutorial
npm i react-router-dom@6
import { React, lazy, Suspense } from "react";
// 导入 Route, Routes 等核心组件
import { Route, Routes, BrowserRouter ,HashRouter } from "react-router-dom";
import Home from "./components/Home";
import About from "./components/About";
import User from "./components/User";
import PageNotFound from "./components/PageNotFound";
import Recommond from "./components/Recommand";
import JapenAnimate from "./components/JapenAnimate";
import ChineseAnimate from "./components/ChineseAnimate";
import NewAnimate from "./components/NewAnimate";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Navigate to={<Home />}></Route>
<Route path="/home" element={<Home />}>
<Route path="/" element={<Navigate to={<Recommond />} />
<Route path="recommand" element={<Recommond />} />
<Route path="new-animate" element={<NewAnimate />} />
<Route path="japan-animate" element={<JapenAnimate />} />
<Route path="chinese-animate" element={<ChineseAnimate />} />
</Route>
<Route path="/user" element={<User />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</BrowserRouter>
);
}
export default App;
两种常用Router:BrowserRouter 、HashRouter
作用:包裹整个应用,只要在页面中写在最外层一次就行了。
BrowserRouter (推荐)
使用H5的history.pushState API实现 ,url显示效果(http://localhost:3000/home)
HashRouter
使用URL的哈希值实现,url显示效果(http://localhost:3000/#/home
配置路由语法:
<Routes>
<Route path="/" element={<Home />} />
<Route path="/user" element={<User />} />
<Route path="/about" element={<About />} />
</Routes>
Routes标签包裹着一个个路由,path对应路径,element对应导入的组件。
配置当无匹配项时,额外的404页面:
<Route path="*" element={<PageNotFound />} />
// 导入NavLink
import { NavLink } from "react-router-dom";
-------------
// 使用,to表示跳转链接
<NavLink to='/home'>
Link 或者 NavLink都会被编译成a标签,并且激活时会自带一个active的类,简单的css,我们可以直接设置该a标签的active类属性。
<NavLink to='/home'>
{(isActive)=>{
// isActive表示该Link是否处于激活状态
}
</NavLink>
用法参考下面
<Routes>
<Route path="/" element={<Navigate to={<Home />}></Route>
<Route path="/home" element={<Home />}>
<Route path="/" element={<Navigate to={<Recommond />} />
<Route path="recommand" element={<Recommond />} />
<Route path="new-animate" element={<NewAnimate />} />
<Route path="japan-animate" element={<JapenAnimate />} />
<Route path="chinese-animate" element={<ChineseAnimate />} />
</Route>
<Route path="/user" element={<User />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
Outlet占位:
注意在使用时,需要配合 Outlet 标签对子路由进行占位,Outlet你可以决定放在父路由页面的任意位置。
语法
import { Outlet } from "react-router-dom";
// 占位
<Outlet />
举个例子:
import TabBar from "../../common/TabBar";
import Tabs from "../Tabs";
import { Outlet } from "react-router-dom";
import SearchBar from "../SearchBar/index";
function Home() {
return (
<div>
<div>
<SearchBar />
<Tabs />
<Outlet />
<TabBar />
</div>
</div>
);
}
export default Home;
我把Outlet放在tabs的下面,tabbar的上面,就是这种效果:
默认渲染一级路由 path=‘/’
默认渲染二级路由,去掉path,添加index属性。
<Route index element={ /> } />
作用:通过js编程的方式进行路由页面跳转,比如从登录界面跳转到关于页。
语法说明:
1.导入useNavigate钩子函数
2.执行钩子函数得到跳转函数
3.执行跳转函数完成跳转
注意:如果在跳转时不想加历史记录,可以添加额外参数replace为true
import { useNavigate } from "react-router-dom";
------------------------
const navigate = useNavigate();
const goHome = () => {
navigate("/home", { replace: true });
};
------------------------------
<button onClick={goHome}></button>
跳转携带参数:有时候不光需要跳转还需要传递参数。
navigate('/about?id=1001')
取参
let [params] = useSearchParams()
let id = params.get('id')
navigate('/about/1001')
取参
let params = useParams()
let id = params.id
详细用法参考下面抽离路由配置文件以及编写路由渲染函数
import { lazy ,Suspense} from "react";
// 示例
Component: lazy(() => import("@/pages/User")),
// 示例
<Route
key={path}
path={path}
element={
<Suspense fallback={<div>加载中</div>}>
<Component />
</Suspense>
}
/>
// 路由配置列表
export const routeList = [
{
labe: "首页",
path: "/",
Component: lazy(() => import("@/pages/Home")),
roles: [USER_ROLES.ADMIN, USER_ROLES.TEST],
redirect: "/home/recommend",
children: [
{
labe: "推荐",
path: "home/recommend",
Component: lazy(() => import("@/pages/Home/components/Recommend")),
roles: [USER_ROLES.ADMIN],
},
{
labe: "新番",
path: "home/new-animate",
Component: lazy(() => import("@/pages/Home/components/NewAnimate")),
},
{
labe: "日漫",
path: "home/japan-animate",
Component: lazy(() => import("@/pages/Home/components/JapenAnimate")),
},
{
labe: "国漫",
path: "home/chinese-animate",
Component: lazy(() => import("@/pages/Home/components/ChineseAnimate")),
},
],
},
{
labe: "排行",
path: "/rank",
Component: lazy(() => import("@/pages/About")),
children: [],
},
{
labe: "我的",
path: "/user",
Component: lazy(() => import("@/pages/User")),
children: [],
},
{
key: "404",
labe: "404页面",
path: "*",
Component: lazy(() => import("@/pages/PageNotFound")),
children: [],
},
];
// 渲染路由配置的方法
export const renderRoutes = (routes) => {
if (routes && routes?.length > 0) {
return routes?.map(({ path, Component, redirect, children }) => {
return children && children?.length > 0 ? (
<Route
key={path}
path={path}
element={
<Suspense fallback={<div>加载中...</div>}>
<Component />
</Suspense>
}
>
{/* 递归渲染子路由 */}
{renderRoutes(children)}
{/* 重定向以及重定向的兜底 */}
{redirect ? (
<>
<Route path={path} element={<Navigate to={redirect} />}></Route>
<Route
path={children[0].path.split("/")[0]}
element={<Navigate to={redirect} />}
/>
</>
) : (
<>
<Route
path={path}
element={<Navigate to={children[0].path} />}
></Route>
<Route
path={children[0].path.split("/")[0]}
element={<Navigate to={children[0].path.split("/")[1]} />}
/>
</>
)}
</Route>
) : (
<Route
key={path}
path={path}
element={
<Suspense fallback={<div>加载中</div>}>
<Component />
</Suspense>
}
/>
);
});
}
};
有空了再写。。。。
更多好文章传送门:https://www.cnblogs.com/operate/p/16082907.html
https://www.jianshu.com/p/e50011ce67cc