引言
📒📒📒欢迎来到小冷的代码学习世界
博主的微信公众号 : 想全栈的小冷,分享一些技术上的文章,以及解决问题的经验
⏩当前专栏:react系列
React 路由
路由就是关键字和组件的映射关系,我们可以用关键字访问和展示对应组件
安装环境
npm i react-router-dom
快速上手 demo
需求: 创建一个可以切换登录页和文章页的路由系统
找到 index.js 创建路由实例对象
语法: 链接组件可以使jsx 也可以是导出的组件 path是访问的路径
createBrowserRouter([
{
path:'/login',
element: <div>登录</div>
})
代码:
index.js
PS : 这里没有app的原因其实就是路由可以自己选择 有没有app作为入口完全看心情 之后会有路由默认设置所以不误在意
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>
</React.StrictMode>
);
效果
抽象路由模块
之前的快速上手 简单的了解了一下路由的语法和使用 ,现在模拟一下日常的开发使用 ,我们需要将路由模块抽象出来
我们创建路由需要对应的文件夹 放入page
文件夹下 一般我们路由的文件夹还会存放一些组件需要的其他资源,内容还是刚才的内容
之后创建 router
文件夹存放路由js文件
之后只需要在 根目录下的index.js
中把路由引入进来 就完成了抽象效果
路由导航
路由系统中的多个路由之间需要进行路由跳转,并且在跳转的同时有可能需要传递参数进行通信
声明式导航
声明式导航是指在代码中 通过 <Link/>
标签去设置要跳转去哪里
语法 : <Linl to="/article">文章</Link>
Login组件内容
import {Link} from "react-router-dom";
export const Login = () => {
return (
<div>
<div>我是登录页面</div>
<Link to="/article">文章</Link>
</div>
)
}
它其实被解析成一个a链接 指向文章页的访问地址(path)
编程式导航
编程式导航是指通过 useNavigate
钩子得到导航方法,以参数+触发事件来控制跳转比起声明式要更加灵活
import {Link, useNavigate} from "react-router-dom";
export const Login = () => {
const nav = useNavigate()
return (
<div>
<div>我是登录页面</div>
{/* 声明式*/}
<Link to="/article">文章</Link>
{/* 编程式*/}
<button onClick={()=>nav("/article")}>文章</button>
</div>
)
}
传参
useSearchParams
代码
Login.jsx
<button onClick={()=>nav('/article?name="jack"')}>文章</button>
Article.jsx
import {useSearchParams} from "react-router-dom";
export const Article = () => {
const [params] = useSearchParams()
const name = params.get('name')
return (
<div>我是文章页面
{name}
</div>
)
}
效果
useParams
这种方式类似 vue的动态路由传参,
-
我们需要再路由页面给路径一个占位符
-
之后编写代码
Login传参 :
<button onClick={()=>nav('/article/1001/JACK')}>文章</button>
Article接受:
const params = useParams(); return ( <div>我是文章页面 <div> id: {params.id}</div> <div> name:{params.name}</div> </div>
效果
嵌套路由
就是多级路由的嵌套 在开发中往往需要来回的跳转 有一级路由包含多个二级路由等等嵌套情况
比如下图:
看成一个管理系统 一个一级路由包含两个二级路由
左侧的列表用于展示路由关键字
右边的路由出口展示点击对应关键字出现的内容
- 使用
children
属性配置路由嵌套关系 - 使用
<Outlet>
组件配置子路由渲染位置
案例
分别创建内容 一级路由 layout 和两个二级路由
然后编写嵌套路由需要的 router
{
path: '/',
element: <Layout/>,
children: [
{
path: 'board',
element: <Board/>
},
{
path: 'about',
element: <About/>
}
]
}
layout代码
import {Link, Outlet} from "react-router-dom";
export const Layout = () => {
return (
<div>一级路由 layout
<div><Link to="/board">面板</Link></div>
<div><Link to="/about">关于</Link></div>
<Outlet/>
</div>
)
}
效果
默认二级路由
当访问的是一级路由的时候 默认的二级路由可以得到渲染
语法:
layout
export const Layout = () => {
return (
<div>一级路由 layout
<div><Link to="/board">面板</Link></div>
<div><Link to="/">关于</Link></div>
<Outlet/>
</div>
)
}
router.js
{
path: '/',
element: <Layout/>,
children: [
{
path: 'board',
element: <Board/>
},
{
index: true,
element: <About/>
}
]
}
效果
404路由
当浏览器输入的路径在路由中无法找到或者不存在 我们就需要一个可以兜底的组件 来提升用户体验
- 准备一个
NotFound
的组件 - 在路由表数组末尾 用
*
号座位path配置路由
NOTFOUND JS
export const Notfound = () => {
return (
<div>
this is NotFound Page
</div>
)
}
router
{
path: '*',
element: <Notfound/>
}
效果
路由模式
各个主流框架的路由常用的路由模式有俩种,history模式和hash模式, ReactRouter分别由 createBrowerRouter 和 createHashRouter 函数负责创建
路由模式 | url表现 | 底层原理 | 是否需要后端支持 |
---|---|---|---|
history | url/login | history对象 + pushState事件 | 需要 |
hash | url/#/login | 监听hashChange事件 | 不需要 |
Hooks
useNavigate
用于编程式导航
语法:
const nav = useNavigate()
<button onClick={()=>nav("/article")}>文章</button>
useSearchParams
用于路由跳转的时候接受传递的参数
<button onClick={()=>nav('/article?name="jack"')}>文章</button>
这个时候我们在文章组件中编写
import {useSearchParams} from "react-router-dom";
export const Article = () => {
const [params] = useSearchParams()
const name = params.get('name')
return (
<div>我是文章页面
{name}
</div>
)
}
useParams
这种方式类似 vue的动态路由传参,
-
我们需要再路由页面给路径一个占位符
-
之后编写代码
Login传参 :
<button onClick={()=>nav('/article/1001/JACK')}>文章</button>
Article接受:
const params = useParams(); return ( <div>我是文章页面 <div> id: {params.id}</div> <div> name:{params.name}</div> </div>