前言
- 前端路由 :
- 一个路径
path
对应 一个组件component
当我们在浏览器中访问一个path
的时候,path
对应的组件会在页面中进行渲染;
- 一个路径
一、创建路由开发环境
使用路由我们还是采用
CRA
创建项目的方式进行基础环境配置;
- 创建具有 路由 项目的 步骤 :
- 创建项目并安装所有依赖:
npm create-react-app xxx(项目名称)
;
- 安装最新的
ReactRouter
包:npm i react-router-dom
;
- 启动项目:
npm run start
;
- 创建项目并安装所有依赖:
二、基础使用
2.1 创建路由并使用
-
目标文件 :
src/router/index.js
;
jsximport React from 'react'; // 导入常见路由的函数 import { createBrowserRouter } from 'react-router-dom'; // 创建router路由实例对象,并配置路由对应关系(路由数组) const router = createBrowserRouter([ { // 需要访问的路径 path: '/', // 和路径对应的组件 // 和 Vue 不同的是,此处是使用 element 接收 组件 或 jsx 的 // 此处写 jsx 是为了演示,在实际开发中,这里写的是组件 element: <div>Login Page</div> } ]); export default router;
-
目标文件 :
src/index.js
;
jsximport React from 'react'; import ReactDOM from 'react-dom/client'; import { RouterProvider } from 'react-router-dom'; import router from './router'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> {/* 路由绑定,注入路由实例对象 */} <RouterProvider router={router} /> </React.StrictMode> );
2.2 抽象路由模块
-
准备工作:
- 在
src
目录下新建一个pages
目录,用来存放组件;Vue
中是views
;
- 在
pages
下,创建两个组件,Login
+Article
;- 创建组件的时候,组件名称一定是首字母大写的;
- 在
-
目标文件 :
src/router/idnex.js
;
jsximport React from 'react'; // 导入常见路由的函数 import { createBrowserRouter } from 'react-router-dom'; // 导入需要的组件 import Login from '../pages/Login'; import Article from '../pages/Article'; // 创建router路由实例对象,并配置路由对应关系(路由数组) const router = createBrowserRouter([ { // 需要访问的路径 path: '/login', // 和路径对应的组件 // 和 Vue 不同的是,此处是使用 element 接收 组件 或 jsx 的 element: <Login /> }, { // 需要访问的路径 path: '/article', // 和路径对应的组件 // 和 Vue 不同的是,此处是使用 element 接收 组件 或 jsx 的 element: <Article /> } ]); export default router;
三、路由导航
- 什么是路由导航?
- 路由系统中的多个路由之间需要进行 路由跳转 ,并且在跳转的同时有可能需要 传递参数进行通信;
3.1 声明式导航
-
在模板中通过
<Link />
组件描述出要跳转到哪里 (通过to
属性进行描述),比如后台管理系统在左侧的菜单通常使用这种方式进行跳转; -
❗ 语法说明 :
- 通过 给组件的
to
属性 指定 要跳转的 路由path ,组件会被渲染为浏览器支持的a
链接; - 如果需要 传参 直接通过 字符串拼接 的方式 拼接参数 即可;
jsximport { Link } from 'react-redux-dom'; <Link to={'path路径'}>XXX</Link>
- 通过 给组件的
-
使用场景:
- 菜单居多;
-
代码展示:
-
优化
Login、Article
组件; -
Login
:jsximport { Link } from 'react-router-dom'; const Login = () => { return ( <div> <div>登陆页面</div> <Link to="/article">文章页面</Link> </div> ); }; export default Login;
-
Article
:jsximport { Link } from 'react-router-dom'; const Article = () => { return ( <div> <div>文章页面</div> <Link to={'/login'}>登录页面</Link> </div> ); }; export default Article;
-
3.2 编程式导航
-
通过
useNavigate
钩子得到的导航方法,然后通过 调用方法 以 命令式 的 形式 进行路由跳转。- 比如想在登录请求完毕之后跳转就可以选择这种方式,更加灵活;
-
❗ 语法说明 :
- 通过调用
navigate
方法传入地址path
实现跳转;
jsximport { useNavigate } from 'react-router-dom'; // useNavigate 的调用必须写在组件里面; // navigate接受一个参数:需要跳转到的路径 const navigate = useNavigate();
- 通过调用
-
使用场景:
- 写在逻辑代码里面;
-
代码展示:
-
优化
Login、Article
组件; -
Login
:jsximport { Link, useNavigate } from 'react-router-dom'; const Login = () => { const navigate = useNavigate(); return ( <div> <div>登陆页面</div> {/* 声明式 */} {/* <Link to={'/article'}>文章页面</Link> */} {/* 编程式 */} <button onClick={() => navigate('/article')}>跳转到文章页面</button> </div> ); }; export default Login;
-
Article
:jsximport { Link, useNavigate } from 'react-router-dom'; const Article = () => { const navigate = useNavigate(); return ( <div> <div>文章页面</div> {/* 声明式 */} {/* <Link to="/login">登录页面</Link> */} {/* 编程式 */} <button onClick={() => navigate('/login')}>跳转登录页面</button> </div> ); }; export default Article;
-
四、路由导航传参
以 编程式导航传参 为例,声明式导航也一样;
4.1 searchParams 传参
-
传参 :
-
字符串拼接(查询字符串);
-
代码展示:
jsximport { useNavigate } from 'react-router-dom'; const navigate = useNavigate(); navigate('/article?userId=1001&articleId=abcd');
-
-
接收参数 :
-
调用
useSearchParams
钩子函数,从返回结果(数组)中解构出params
对象,调用该对象的get
方法,将需要的 参数名字 传递给get
方法即可;jsximport { useSearchParams } from 'react-router-dom'; const [params] = useSearchParams(); console.log(params.get('userId'));
-
4.2 params 传参
-
传参 :
-
语法 :
-
需要对路由规则数组进行改造(和Vue一样,用
/:参数名
进行占位);jsxconst router = createBrowserRouter([ { // 需要访问的路径 path: '/login/:userId/:likeId', // 和路径对应的组件 // 和 Vue 不同的是,此处是使用 element 接收 组件 或 jsx 的 element: <Login /> } ]);
-
-
代码展示:
jsximport { useNavigate } from 'react-router-dom'; const navgiate = useNavigate(); navigate('/article/1001/abcd');
-
-
接收参数 :
-
语法 :
- 导入并调用
useParams
钩子函数,该钩子函数的返回值是个对象,传递的参数在这个对象中,通过点语法进行读取;
- 导入并调用
-
代码展示:
jsximport { useParams } from 'react-router-dom'; const params = useParams(); console.log(params);
-
五、嵌套路由配置
- 嵌套路由:
- 在一级路由中又内嵌了其他路由,这种关系就叫做嵌套路由;
- 嵌套至一级路由内的路由又称为二级路由 ;
-
❗ 实现步骤 :
- 使用
children
属性 (属性值是个** **) 配置 路由 嵌套关系; - 使用
<Outlet />
组件 配置 二级路由 渲染位置 (二级路由出口);- 这个组件在哪里,二级路由渲染的位置就在哪里;
- 使用
-
代码展示:
-
创建三个组件
Layout(一级路由)、About(二级路由)、Board(二级路由)
;jsx// About 组件 const About = () => { return <div>我是关于组件</div>; }; export default About; // Board 组件 const Board = () => { return <div>我是面板组件</div>; }; export default Board; // Layout 组件 import { Link, Outlet, useNavigate } from 'react-router-dom'; const Layout = () => { const navigate = useNavigate(); return ( <div> <div>一级路由</div> <Link to="/layout/board">面板</Link> <button onClick={() => navigate('/layout/about')}>关于</button> {/* 二级路由出口 */} <Outlet /> </div> ); }; export default Layout;
-
目标文件:
router/index.js
;jsx// 只写部分代码 import Layout from '../pages/Layout'; import About from '../pages/About'; import Board from '../pages/Board'; const router = createBrowserRouter([ { path: '/layout', element: <Layout />, children: [ { path: 'about', element: <About /> }, { path: 'board', element: <Board /> } ] }, ]);
-
-
效果演示:
六、默认二级路由配置
-
当访问一级路由的时候,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉
path
,设置index
属性为true
即可;Vue
中是将二级路由的path
置为空串;
-
代码展示:
jsxconst router = createBrowserRouter([ { path: '/layout', element: <Layout />, children: [ { // 设置默认二级路由,一级路由访问的时候,它也能得到渲染 // path: 'about', // 访问的时候,直接访问 /layout 即可 index: true, element: <About /> }, { path: 'board', element: <Board /> } ] } ]);
-
效果演示:
七、404路由配置
-
场景 :
- 当浏览器输入的url地址在整个路由配置中都找不到对应的
path
,为了用户体验,可以使用404
兜底组件进行渲染;
- 当浏览器输入的url地址在整个路由配置中都找不到对应的
-
实现步骤 :
- 准备一个
NotFound
组件; - 在路由规则数组的末尾,以
*
作为路由path
配置路由;
- 准备一个
-
代码展示:
- 目标文件:
router/index.js
;
jsximport NotFound from '../pages/NotFound'; const router = createBrowserRouter([ ..., { path: '*', element: <NotFound /> } ]);
- 目标文件:
八、路由模式
- 各个主流框架的路由常用的路由模式有两种,
history
模式 和hash
模式; - ReactRouter分别由:
createBrowerRouter
和createHashRouter
函数负责创建;
路由模式 | url表现 | 底层原理 | 是否需要后端支持 |
---|---|---|---|
history |
url/login |
history 对象 + pushState 事件 |
需要 |
hash |
url/#/login |
监听hashChange 事件 |
不需要 |
- 更换创建路由实例的方法即可;