使用路由前,首先要进行安装

yarn add react-router-dom     或者  npm i react-router-dom

直接安装的话,默认安装的是6版本的,所有下面介绍的也是6版本的

目录

路由模式

实现一个简单路由

嵌套路由

动态路由

获取路径(查询)参数

 编程式导航

useRoutes


路由模式

  • 常用的有3种,浏览器模式BrowserRouter,hash模式HashRouter,历史模式HishtoryRouter
  • 浏览器模式BrowserRouter会使我们地址栏的路由看着更像是一个正常的路由
  • 而hash模式的路由会多出一个#号

实现一个简单路由

1. 首先在index.js文件中做出配置    React的index.js页面相当于Vue的main.js,入口

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// 1. 引入BrowserRouter,并重命名为Router,想要什么路由模式,就引入对应的路由模式
import { BrowserRouter as Router } from 'react-router-dom'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    {/* 2. 使用Router进行包裹,这样在App页面的所有地方都可以直接使用路由了 */}
    <Router>
        <App />
    </Router>
  </React.StrictMode>
);

reportWebVitals();

2. 在App.js文件中进行各种路由配置

App.js

import React from 'react'
import { Routes, Route, Link } from 'react-router-dom'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'

export default function App() {
  return (
    <div>
      <h2>App</h2>
      <hr />
      <Link to="/">点击跳转Home</Link> | <Link to="/about">点击跳转About</Link>
      <Routes>
        <Route path="/" element={<Home />}></Route>
        <Route path="/about" element={<About />}></Route>
      </Routes>
    </div>
  )
}
  • Routes是5版本的Switch升级而来,Routes只能包裹Route
  • 被Routes包裹的Route,只会匹配第一个符合要求的路由(类似于Switch...case,多选一)

路由是/about时,只会匹配About组件,而不会匹配Home 

  • Route指定路由规则,path指定路径,而element指定要渲染的组件
  • Link类似于Vue的router-link,可以显示的声明跳转,里面的to属性就是跳转的路由

嵌套路由

  • 路由里面嵌套路由,也就是Route里面嵌套Route,在谁的里面嵌套,就是谁的子路由
  • 需要在父级路由里面声明路由出口(Outlet),不然子路由对应的组件渲染那去呢

App.js

import React from 'react'
import { Routes, Route, Link } from 'react-router-dom'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'
import Music from './pages/Music.jsx'
import Movie from './pages/Movie.jsx'

export default function App() {
  return (
    <div>
      <h2>App</h2>
      <hr />
      <Link to="/">点击跳转Home</Link> | <Link to="/about">点击跳转About</Link>
      <Routes>
        <Route path="/" element={<Home />}></Route>
        <Route path="/about" element={<About />}>
          <Route index element={<Music />}></Route>
          <Route path="music" element={<Music />}></Route>
          <Route path="movie" element={<Movie />}></Route>
        </Route>
      </Routes>
    </div>
  )
}
  • Route的index属性,类似于Vue 的重定向,直接指定路由进去后默认渲染的子路由

About.jsx      (子级路由Music和Movie的父级路由)

import React from 'react'
import { Outlet, Link } from 'react-router-dom'

export default function About() {
  return (
    <div>
      <h2>About</h2>
      <p>下面是子级路由</p>
      <Link to="music">跳转Music</Link> | <Link to="movie">跳转Movie</Link>
      <Outlet></Outlet>
    </div>
  )
}
  • 在父级路由里面,子级路由可以直接写,不用带/和父级路由,它会根据父路由自动拼接

动态路由

  • 在对应的路由后面,无论添加什么,都会匹配同一个组件
import React from 'react'
import { Routes, Route, Link } from 'react-router-dom'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'
import Music from './pages/Music.jsx'
import Movie from './pages/Movie.jsx'
import My from './pages/My.jsx'

export default function App() {
  return (
    <div>
      <h2>App</h2>
      <hr />
      <Link to="/">点击跳转Home</Link> | <Link to="/about">点击跳转About</Link>{' '}
      <Routes>
        {/* 普通路由 */}
        <Route path="/" element={<Home />}></Route>
        {/* 嵌套路由 */}
        <Route path="/about" element={<About />}>
          <Route index element={<Music />}></Route>
          <Route path="music" element={<Music />}></Route>
          <Route path="movie" element={<Movie />}></Route>
        </Route>
        {/* 动态路由 */}
        <Route path="/my/:id" element={<My />}></Route>
      </Routes>
    </div>
  )
}

获取动态路由参数

  1. useParams()    返回的是一个动态路由参数的对象

My.jsx

import React from 'react'
import { useParams } from 'react-router-dom'

export default function My() {
  //   let { id } = useParams()
  //   console.log(id)
  let params = useParams()
  console.log(params)
  return (
    <div>
      <h2>My</h2>
      <p>获取到的动态路由参数为:{params.id}</p>
    </div>
  )
}

获取路径(查询)参数

  • 类似于这种:  to = "/friend?name=张三"   获取问号后面的

使用 useLocation()

App.js

import React from 'react'
import { Routes, Route, Link } from 'react-router-dom'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'
import Music from './pages/Music.jsx'
import Movie from './pages/Movie.jsx'
import My from './pages/My.jsx'
import Friend from './pages/Friend.jsx'

export default function App() {
  return (
    <div>
      <h2>App</h2>
      <hr />
      <Link to="/">点击跳转Home</Link> | <Link to="/about">点击跳转About</Link>{' '}
      | <Link to="/friend?name=zs">点击跳转Friend</Link>
      <Routes>
        {/* 普通路由 */}
        <Route path="/" element={<Home />}></Route>
        {/* 嵌套路由 */}
        <Route path="/about" element={<About />}>
          <Route index element={<Music />}></Route>
          <Route path="music" element={<Music />}></Route>
          <Route path="movie" element={<Movie />}></Route>
        </Route>
        {/* 动态路由 */}
        <Route path="/my/:id" element={<My />}></Route>
        {/* 查询参数 */}
        <Route path="/friend" element={<Friend />}></Route>
      </Routes>
    </div>
  )
}

Friend.jsx

import React from 'react'
import { useLocation } from 'react-router-dom'

export default function Friend() {
  let location = useLocation()
  console.log(location)
  return (
    <div>
      <h2>Friend</h2>
      <p>获取到的查询参数为:{location.search.slice(1).split('=')[1]}</p>
    </div>
  )
}

使用useSearchParams()       这个相比useLocation(),可以直接获取查询参数的值

  • 底层使用了URLSearchParams()对象,里面包含了很多查询参数的方法
  • 返回的是一对值,用数组进行接收

App.js

import React from 'react'
import { Routes, Route, Link } from 'react-router-dom'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'
import Music from './pages/Music.jsx'
import Movie from './pages/Movie.jsx'
import My from './pages/My.jsx'
import Friend from './pages/Friend.jsx'

export default function App() {
  return (
    <div>
      <h2>App</h2>
      <hr />
      <Link to="/">点击跳转Home</Link> | <Link to="/about">点击跳转About</Link>{' '}
      | <Link to="/friend?name=zs">点击跳转Friend</Link>
      <Routes>
        {/* 普通路由 */}
        <Route path="/" element={<Home />}></Route>
        {/* 嵌套路由 */}
        <Route path="/about" element={<About />}>
          <Route index element={<Music />}></Route>
          <Route path="music" element={<Music />}></Route>
          <Route path="movie" element={<Movie />}></Route>
        </Route>
        {/* 动态路由 */}
        <Route path="/my/:id" element={<My />}></Route>
        {/* 查询参数 */}
        <Route path="/friend" element={<Friend />}></Route>
      </Routes>
    </div>
  )
}

 Friend.jsx

import React from 'react'
import { useLocation, useSearchParams } from 'react-router-dom'

export default function Friend() {
  // useLocation()
  let location = useLocation()
  console.log('useLocation()', location)
  // useSearchParams()
  let [search, serSearch] = useSearchParams()
  console.log('useSearchParams()', search)
  // 修改查询参数,执行的是覆盖操作,如果有多个查询参数,则需要补全
  const changeName = () => {
    serSearch({
      name: 'ls',
    })
  }
  return (
    <div>
      <h2>Friend</h2>
      <p>获取到的查询参数为:{location.search.slice(1).split('=')[1]}</p>
      <p>获取到的查询参数为:{search.get('name')}</p>
      <button onClick={changeName}>修改传过来查询参数:name</button>
    </div>
  )
}

 编程式导航

useNavigate(to[,options])     5使用的是useHistory()

  • to是跳往的路由地址,options可选,路由配置项,可以传递一些参数什么的

Home.jsx

import React from 'react'
import { useNavigate } from 'react-router-dom'

export default function Home() {
  const navigate = useNavigate()
  const toAbout = () => {
    navigate('/about?age=24', {
      state: {
        name: 'zs',
      },
      // 则不可回退
      replace: true,
    })
  }
  return (
    <div>
      <h2>Home</h2>
      <button onClick={toAbout}>跳往About</button>
    </div>
  )
}

About.jsx

import React from 'react'
import { useLocation } from 'react-router-dom'

export default function About() {
  const params = useLocation()
  console.log(params)
  return (
    <div>
      <h2>About</h2>
    </div>
  )
}

Link

  • 可以直接指定要跳转的路由   to属性指定路由,最终会转换为a元素
<Link to="music">跳转Music</Link> | <Link to="movie">跳转Movie</Link>

NavLink

  • 可以直接指定要跳转的路由,选中的时候,会比Link多一个active的类名。我们可以通过这个类名来指定一些选中时的样式,最终会转换为a元素

  • to属性指定路由
  • style属性指定样式,是个函数形式,函数的第一个参数是个对象,里面有个isActive表是否选中,是一个布尔值

未选中

选中

  • 我们也可以直接指定一个calssName
import React from 'react'
import { NavLink } from 'react-router-dom'

export default function About() {
  let borderStyle = {
    border: '1px solid pink',
    color: 'red',
  }
  return (
    <div>
      <h2>About</h2>
      <NavLink
        to="music"
        style={({ isActive }) => {
          console.log(isActive)
          if (isActive) {
            return borderStyle
          }
        }}
      >
        跳转Music
      </NavLink>
      <NavLink to="movie">跳转Movie</NavLink>
    </div>
  )
}

Navigate

  • to属性指定跳转的路由,replace表是否替换(不保留历史记录)
  • 一般做动态路由用,或者做权限
import React, { useState } from 'react'
import { useNavigate, Navigate } from 'react-router-dom'

export default function Home() {
  let [flag, setFlag] = useState(false)
  const toabout = () => {
    setFlag((flag = !flag))
  }
  return (
    <div>
      <h2>Home</h2>
      <button onClick={toabout}>点击跳转About</button>
      {flag && <Navigate to="/about">跳往About</Navigate>}
    </div>
  )
}

useRoutes

  • 用法类似于vue的路由

单独创建一个router.js文件,存放路由配置规则

router.js

import Home from '../pages/Home.jsx'
import About from '../pages/About.jsx'
import Login from '../pages/Login.jsx'
import NotFound from '../pages/NotFound.jsx'
import Music from '../pages/Music.jsx'
import Movie from '../pages/Movie.jsx'

const routes = [
  {
    path: '/',
    element: <Home />,
    meta: {
      title: '首页',
      hide: false,
    },
  },
  {
    path: '/about',
    element: <About />,
    meta: {
      title: '关于',
      hide: false,
    },
    children: [
      {
        path: 'music',
        element: <Music />,
        meta: {
          title: '音乐',
          hide: false,
        },
      },
      {
        path: 'movie',
        element: <Movie />,
        meta: {
          title: '电影',
          hide: false,
        },
      },
    ],
  },
  {
    path: '/login',
    element: <Login />,
    meta: {
      hide: true,
    },
  },
  {
    path: '*',
    element: <NotFound />,
    meta: {
      hide: true,
    },
  },
]

export default routes

App.js

import React from 'react'
import routes from './routes/routes'
import { useRoutes, NavLink } from 'react-router-dom'

export default function App() {
  const element = useRoutes(routes)
  console.log(routes)
  return (
    <div>
      <h2>App</h2>
      {/* 显示声明 */}
      <ul>
        {routes.map(
          (item) =>
            !item.meta.hide && (
              <li key={item.path}>
                <NavLink to={item.path}>{item.meta.title}</NavLink>
                {item.children && (
                  <ul>
                    {item.children.map((items) => (
                      <li key={items.path}>
                        <NavLink to={item.path + '/' + items.path}>
                          {items.meta.title}
                        </NavLink>
                      </li>
                    ))}
                  </ul>
                )}
              </li>
            )
        )}
      </ul>

      {/* 路由配置 */}
      {element}
    </div>
  )
}

原文链接:https://blog.csdn.net/qq_52845451/article/details/127149936

最后修改:2023 年 10 月 30 日
如果觉得我的文章对你有用,请随意赞赏