文章目录
0.准备
前端路由回顾:
一个路径path对应一个组件component,当访问一个路径时对应的组件会在页面进行渲染
环境搭建:
javascript
创建项目:npx create-react-app my-react-router
进入项目目录:cd my-react-router
安装所有依赖:npm i
安装ReactRouter包:npm i react-router-dom
启动项目:npm run start
1.示例:快速创建一个切换登录页和文章页的路由系统
javascript
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// import App from './App';
import reportWebVitals from './reportWebVitals';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
// 创建路由实例对象
const router = createBrowserRouter([
{
path: '/login',
element: <div>我是登录页</div>
},
{
path: '/article',
element: <div>我是文章页</div>
}
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router}></RouterProvider>
{/* <App /> */}
{/* 此处为何不需要根组件App?
因为RouterProvider已经包含了根组件,
具体来说:就是,在React Router v6中,RouterProvider组件充当了根路由组件的角色。
这意味着你可以直接将你的应用内容包裹在<RouterProvider>标签内,
而不需要额外的顶层App组件来包裹整个应用程序。 */}
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
成功标志:地址栏localhost:3000/login
有显示
*注释掉根组件App,意味着由路由来管理页面
2.实际开发中的路由配置
step1:在配置模块新增两个组件
javascript
┌─src
├─pages 业务页面文件存放的目录
│ ├─article
│ │ └─index.js 文章页
│ └─login
│ └─index.js 登录页
****代码****
//article/index.js
const Article=()=>{
return <div>我是文章页</div>;
}
export default Article
//login/index.js
const Login=()=>{
return <div>我是登录页</div>
})
export default Login
step2:新增router模块,引入组件,配置对应关系
新增模块src/router/index.js
javascript
//导入
import Login from "../page/login"
import Article from "../page/article"
import {createBrowserRouter} from 'react-router'
//创建路由实例对象
const router=createBrowserRouter({
{
path:'/login',
element:<Login />
},
{
path:'/article',
element:<Article />
}
})
export default router
step3:在应用入口文件src/index.js注入router实例
javascript
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// import App from './App';
import reportWebVitals from './reportWebVitals';
import { RouterProvider } from 'react-router-dom';
//引入子路由
import router from './router'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router}></RouterProvider>
</React.StrictMode>
);
reportWebVitals();
3.路由导航以及传参
路由系统中的多个路由之间进行的路由跳转(并传参)
回顾:声明式导航VS编程式导航,查询参数传参VS动态参数传参
3.1.React中的声明式导航VS编程式导航
3.1.1.声明式导航
通过<Link to='/article?id=1001&name=zs'>跳转文章页</Link>
标签,描述要跳转去哪个路由
to属性 :指定要跳转到的路由path,组件会渲染为a标签,若要传参就用字符串拼接即可
常见场景:左侧菜单栏跳转
javascript
//article页
import {Link} from 'react-router-dom';
const Article=()=>{
return(
<div>
<h1>文章详情</h1>
<nav>
<Link to="/login">跳转登录页</Link>
</nav>
</div>
)
}
export default Article
3.1.2.编程式导航
通过调用useNavigate钩子函数以命令的形式进行跳转
常见场景:登录后跳转
javascript
//login页
import { useNavigate } from 'react-router-dom';
const Login = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/article');
}
return (
<div>
<h1>登录页面</h1>
<button onClick={handleClick}>返回文章页</button>
</div>
)
}
export default Login
3.2.React中的查询参数传参VS动态路由传参
路由传参 | 查询参数传参 | 动态路由传参 |
---|---|---|
配置路由 | 无需配置 | 语法:path='article/:参数名' *** ** * ** *** 示例:path='article/:id' |
声明式导航 | 语法:<Link to='/article?参数名1=参数值1&参数名2=参数值2'> *** ** * ** *** 示例:<Link to='/article?name=张三&age=18'> |
语法: <Link to='/article/参数值'> *** ** * ** *** 示例:<Link to='/article/1001'> |
编程式导航 | navigate({pathname:'/article',search:'?name=张三&age=18''}) |
navigate( `/article/${id}`); |
接收参数 | const [searchParams] = useSearchParams();const name = searchParams.get('name'); |
const { id } = useParams(); |
4.嵌套路由
一级路由中嵌套二级路由
children
属性:在一级路由的路由配置中写二级路由
javascript
const router=createBrowserRouter({
{
path:'/login/:id',
element:<Login />,
children:[
{
path:'/login111/:id',
element:<Login111 />,
},
{
path:'/login222/:id',
element:<Login222 />,
},
]
},
}
//并在一级路由的页面中写二级路由出口
//Login.js
<Login111 />
5.默认二级路由
访问一级路由时,默认二级路由也能得到渲染
做法:在二级路由的位置去掉path,设置index属性为true
javascript
const router=createBrowserRouter({
{
path:'/login/:id',
element:<Login />,
children:[
{
//path:'/login111/:id',
index:true,
element:<Login111 />,
},
{
path:'/login222/:id',
element:<Login222 />,
},
]
},
}
6.404路由
当浏览器都找不到对应path,跳转到404页面
javascript
//NotFound.js
const NotFound=()=>{
return <h1>404 not found!!!</h1>
})
export default NotFound
const router=createBrowserRouter({
{
path:'*',
element:<NotFound />
}
})
7.两种路由模式:hash模式和history模式
7.1.hash模式
有#号,如:url/#/login,监听hashChange事件,不需要后端文件
7.2.history模式
监听history对象和pushState事件