• 作者:老汪软件技巧
  • 发表时间: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 才能展示