- 作者:老汪软件技巧
- 发表时间:2024-08-22 11:02
- 浏览量:
前言
前端路由的作用就是将单页应用的状态处理成多页路由的样子,react 和 vue 的路由是一样的,一个地址对应一个组件,下面看看 react-router 的用法
安装
在 vue 中想要使用 router 需要进行安装,react 一样也需要安装
目前 react-router 全称为 react-router-dom ,当前最新版是 6
安装指令如下
npm i react-router-dom@6
Link
接下来实现一个效果,点击首页展示首页这个页面内容,点击关于页展示关于这个页面内容
import React from 'react';
import { BrowserRouter, Link, Routes, Route } from 'react-router-dom'
const Home = () => <div>this is homediv>
const About = () => <div>this is aboutdiv>
const App = () => {
return (
<div className='app'>
<BrowserRouter>
<Link to='/'>首页 | Link>
<Link to='about'>关于Link>
<Routes>
<Route path='/' element={<Home />}>Route>
<Route path='/about' element={<About />}>Route>
Routes>
BrowserRouter>
div>
);
};
export default App;
直接在根组件中写两个页面出来,路由的写法需要用 BrowserRouter 进行包裹,这其实就是 history 模式的路由,哈西模式的路由是 HashRouter ,另外你需要引入 Link ,这其实就是 a 标签。 react 中的路由入口是 Routes ,里面去写单个的路由,单个路由需要写 path 和 element
这是用 a 标签去跳转页面,还有个方法是用 button 来跳转页面
Button
vue 中想要在组件中跳路由需要引入 useRouter,拿 router 去 push 跳转
而 react 则是引入一个 hooks,useNavigate,调用这个 hooks 就可以得到一个跳转路由的方法
import React from 'react';
import { BrowserRouter, Link, Routes, Route, useNavigate } from 'react-router-dom'
const Home = () => {
const navigate = useNavigate()
return (
<div>
this is home
<button onClick={() => navigate('/about')}>跳去关于页面button>
div>
)
}
const About = () => <div>this is aboutdiv>
const App = () => {
return (
<div className='app'>
<BrowserRouter>
<Link to='/'>首页 | Link>
<Link to='about'>关于Link>
<Routes>
<Route path='/' element={<Home />}>Route>
<Route path='/about' element={<About />}>Route>
Routes>
BrowserRouter>
div>
);
};
export default App;
当然,history 可以有回退的功能,就是可以缓存历史访问的页面,你想要关掉这个功能,只需要给 navigate 加入第二个参数: replace: true
这样,你就无法回退了
你会发现 react 中需要引入的东西还是蛮多的,这里也总结下
BrowserRouter,HashRouter
history 模式和 hash 模式
Link
to 属性用于跳到指定的路径
Routes
路由的入口,类似 vue 的 router-view
Route
单个路由匹配,path 用于匹配路径,element 用于匹配组件
useNavigate
const navigate = useNavigate()
路由传参
之前讲 vue 的路由传参有四种方法,这里 react 有两种方式进行传参
方法一:Search传参
这种方式就是原生 js 写法,直接 ? 拼接 url 后面传递
其他页面想要拿到这个参数需要引入一个 hooks,useSearchParams ,这个方法的实例是一个数组,数组中用 get 拿到参数
import React from 'react';
import { BrowserRouter, Link, Routes, Route, useNavigate, useSearchParams } from 'react-router-dom'
const Home = () => {
const navigate = useNavigate()
return (
<div>
this is home
<button onClick={() => navigate('/about?id=123' , { replace: true })}>跳去关于页面button>
div>
)
}
const About = () => {
let [ params ] = useSearchParams()
console.log(params.get('id'));
return (
<div>this is aboutdiv>
)
}
const App = () => {
return (
<div className='app'>
<BrowserRouter>
<Link to='/'>首页 | Link>
<Link to='about'>关于Link>
<Routes>
<Route path='/' element={<Home />}>Route>
<Route path='/about' element={<About />}>Route>
Routes>
BrowserRouter>
div>
);
};
export default App;
你若用 Link 这样跳转页面,useSearchParams 是拿不到参数的,这种方法只能用 navigate
方法二:Params传参
这种方法你就可以传参不用 ?,直接用 / 拼接即可,为了防止这个参数也是个路径,你需要在接收方引入一个 hooks,useParams,并且传参时需要在 Routes 中的路径中指明 path 有参数,并且用:写上参数名
import React from 'react';
import { BrowserRouter, Link, Routes, Route, useNavigate, useSearchParams, useParams } from 'react-router-dom'
const Home = () => {
const navigate = useNavigate()
return (
<div>
this is home
<button onClick={() => navigate('/about/123' , { replace: true })}>跳去关于页面button>
div>
)
}
const About = () => {
let params = useParams()
console.log(params.id);
return (
<div>this is aboutdiv>
)
}
const App = () => {
return (
<div className='app'>
<BrowserRouter>
<Link to='/'>首页 | Link>
<Link to='about'>关于Link>
<Routes>
<Route path='/' element={<Home />}>Route>
<Route path='/about/:id' element={<About />}>Route>
Routes>
BrowserRouter>
div>
);
};
export default App;
其实还有个 state 传参,不过现在最新的react版本已经不支持了
总结navigate('/about?id=123') 用 useSearchParams() 接受参数navigate('/about/123') 用 useParams() 接受参数二级路由
下面实现一个二级页面的效果,一个布局栏页面中又有一个文章页面和一个发布页面
App.jsx
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './views/Home';
import Layout from './views/Layout';
import Article from './views/layout-views/Article'
import Publish from './views/layout-views/Publish'
const App2 = () => {
return (
<div>
<BrowserRouter>
<Routes>
<Route path='/' element={<Home />}>Route>
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route path='article' element={<Article/>}>Route>
<Route path='publish' element={<Publish/>}>Route>
Route>
Routes>
BrowserRouter>
div>
);
};
export default App2;
Layout.jsx
import React from 'react';
import { Link, Outlet } from 'react-router-dom'
const Layout = () => {
return (
<div>
<header style={{height: '80px', backgroundColor: '#eee'}}>headerheader>
<section style={{display: 'flex'}}>
<aside style={{width: '200px', height: 'calc(100vh - 80px)', backgroundColor: 'yellow'}}>
<ul>
<li><Link to={'/layout/article'}>文章Link>li>
<li><Link to={'/layout/publish'}>发布Link>li>
ul>
aside>
<section>
<Outlet />
section>
section>
div>
);
};
export default Layout;
这里的写法和 vue 有异曲同工之妙,二级路由无需打斜杠 / ,同样的在 layout 中再写一个 Route
二级路由需要引入一个入口 Outlet,Route 中的页面才会在这里面展示
当然,我们也可以来到 layout 默认展示一个二级页面,实现方法有两种,这里以默认展示 article 页面为例
实现方法一:直接将 article 的 path 去掉,换成 index
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route index element={<Article/>}>Route>
<Route path='publish' element={<Publish/>}>Route>
Route>
这样做,article 的路径就是 layout 的路径
实现方法二: Navigate
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route path='' element={<Navigate to='/layout/article'/>}>Route>
<Route path='article' element={<Article/>}>Route>
<Route path='publish' element={<Publish/>}>Route>
Route>
写法上就是再写一个Route,用作重定向
最后
对比 vue,react 的路由写法还是比较复杂一点, react 中引入的东西还是比较多的,vue 无论一级二级路由都是一个写法,react 的写法是一级路由入口直接 BrowserRouter,而二级路由则需要写一个Outlet 才能展示