react 项目路由配置(react-router-dom 版本 v6.3、v6.4)

根据 react-router-dom 的版本,有不同的方式

一、react-router-dom v6.3

用到的主要 api:

  • BrowserRouter
  • useRoutes
  • Outlet

下面是详细步骤:

1、index.js

  • BrowserRouter 用来实现 单页的客户端路由
  • 使用 BrowserRouter 包裹 App
  • 放在 顶级 位置,重要!!
  • 支持嵌套路由,用于 history 模式
  • hash 模式使用 HashRouter
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <BrowserRouter>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </BrowserRouter>
);

// 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();

如果遇到下图这种报错,就是没有将 BrowserRouter 像上图一样放在 顶级,一定要放顶级!

在这里插入图片描述

2、routes.js

用 数组 描述路由,包含必要参数 pathelementchildren

例如:

import { UserOutlined } from "@ant-design/icons";
import Abroad from "./pages/Abroad";
import Domestic from "./pages/Domestic";
import Layout from "./layout/index";
import { Navigate } from "react-router-dom";

const routes = [
  {
    title: "平台管理",
    path: "/manage",
    element: <Layout />,
    icon: <UserOutlined />,
    children: [
      {
        title: "境内平台管理",
        path: "/manage/domestic",
        element: <Domestic />,
        icon: <UserOutlined />,
      },
      {
        title: "境外平台管理",
        path: "/manage/abroad",
        element: <Abroad />,
        icon: <UserOutlined />,
      },
    ],
  },
  {
    path: "/",
    element: <Navigate to="/manage/domestic" />,
  },
];

export default routes;

3、App.js

使用 useRoutes 渲染出一级路由,参数即为我们在上一步的路由数组

  • useRoutes 是 react-router-dom 库中提供的一个 Hook,用于 基于路由配置生成路由匹配器(Router Matcher)的方法
  • useRoutes 接收的路由配置对象应该是一个由 若干个路由配置组成的数组,每个路由配置包含以下属性:
    • path:字符串类型,表示 URL 路径匹配规则;
    • element:React 组件,表示如果 URL 匹配成功后要显示的组件;
    • children:嵌套子路由的路由配置数组。
import React from "react";
import { useRoutes } from "react-router-dom";
import routes from "./routes";

const App = () => {
  const element = useRoutes(routes);
  return <>{element}</>;
};

export default App;

4、layout.jsx

实际场景,如后台管理项目,需要展示多级路由,我们一般会创建一个layout文件

  • 按照 左 Menu右 Content 的设定来举例
  • 嵌套的二级路由,使用 outlet 渲染(类似于vue中的 <router-view>
  • 例子中,包含了一些菜单处理的代码,如递归渲染、默认选中,可选择性观看
import React, { useState } from "react";
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
import { Layout, Menu, Button, theme } from "antd";
import { Outlet, useNavigate, useLocation } from "react-router-dom";
import routes from "../routes/index";

const { Header, Sider, Content } = Layout;

// Menu格式处理
function getMenu(rout) {
  const rs = rout.map((item) => {
    return {
      label: item.title,
      key: item.path,
      icon: item.icon,
      children: item.children && getMenu(item.children),
    };
  });
  return rs;
}

// 递归层级
function findParents(key, tree) {
  let parents = [];
  function findParent(nodes, key) {
    for (let node of nodes) {
      if (node.path === key) {
        return true;
      }
      if (node.children && findParent(node.children, key)) {
        parents.push(node.path);
        return true;
      }
    }
    return false;
  }
  findParent(tree, key);
  parents.push(key);
  return parents;
}

// 获取当前路由所在层级
function getOpenKeys(pathname, list) {
  if (!pathname) return ["/manage", "/manage/domestic"];
  let keys = findParents(pathname, list);
  return keys;
}

const App = () => {
  const [collapsed, setCollapsed] = useState(false);
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken();

  // 递归获取有效菜单项
  const list = routes.filter((item) => item.title);
  const items = getMenu(list);

  // 菜单,默认展开、选中处理
  const location = useLocation();
  const keys = getOpenKeys(location.pathname, list);
  const defaultSelectedKeys = keys;
  const defaultOpenKeys = keys;

  // 跳转
  let navigate = useNavigate();
  function handleClick(e) {
    navigate(e.key);
  }

  return (
    <Layout>
      <Sider trigger={null} collapsible collapsed={collapsed}>
        <div style={{ width: "100%", height: "80px" }}></div>
        {/* 菜单 */}
        <Menu
          mode="inline"
          theme="dark"
          defaultSelectedKeys={defaultSelectedKeys}
          defaultOpenKeys={defaultOpenKeys}
          onClick={handleClick}
          items={items}
        ></Menu>
      </Sider>
      <Layout>
        <Header
          style={{
            padding: 0,
            background: colorBgContainer,
          }}
        >
          <Button
            type="text"
            onClick={() => setCollapsed(!collapsed)}
            style={{ marginBottom: 16 }}
          >
            {collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
          </Button>
        </Header>
        <Content
          style={{
            margin: "24px 16px",
            padding: 24,
            minHeight: 280,
            background: colorBgContainer,
            borderRadius: borderRadiusLG,
            overflowY: "auto",
          }}
        >
          {/* 二级路由 */}
          <Outlet />
          
        </Content>
      </Layout>
    </Layout>
  );
};
export default App;

v6.3 的版本,路由设置到此结束,接下来是 v6.4

二、react-router-dom v6.4

主要 api:

  • createBrowserRouter
  • RouterProvider
  • Outlet

在 v6.3 方案的基础上,换掉 index.js 和 App.js 即可

1、index.js

BrowserRouter 的使用去掉


import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

// v6.3 使用此API,v6.4使用会报错
// import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  // <BrowserRouter>
  <React.StrictMode>
    <App />
  </React.StrictMode>
  // </BrowserRouter>
);

// 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();

2、App.js

useRoutes 的使用去掉,增加 createBrowserRouterRouterProvider 的相关设置

  • createBrowserRouter 创建路由
  • 挂载到 RouterProviderrouter

import React from "react";
import routes from "./routes";

// v6.3 userRoutes钩子
// import { useRoutes } from "react-router-dom";
// const App = () => {
//   const element = useRoutes(routes);
//   return <>{element}</>;
// };

// v6.4 createBrowserRouter + RouterProvider
import { createBrowserRouter, RouterProvider } from "react-router-dom";
const router = createBrowserRouter(routes);
const App = () => {
  return (
    <>
      <RouterProvider router={router} />
    </>
  );
};

export default App;

然后就完成啦~

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值