嵌套路由

164 阅读3分钟

嵌套路由

在React中嵌套路由是将一个或多个路由组件嵌套在其他路由组件中。通过嵌套路由,我可以在父级路由组件的路径下定义子级路由组件的路径,形成层级结构的路由配置。

使用嵌套路由可以实现以下功能:

  • 复杂页面结构:通过嵌套路由,可以构建复杂的页面结构,将不同层级的组件与对应的URL路径进行关联。
  • 可扩展路由配置:嵌套路由使得路由配置更具可扩展性,可以轻松添加、修改和删除子级路由。

嵌套路由的基本概念:

  • 父路由组件:包含子路由的组件。
  • 子路由组件:在父路由组件中嵌套的组件。
  • <Outlet> 组件:用于在父路由组件中渲染子路由匹配的组件。

嵌套路由的使用方法

项目中包含一个主布局组件 MainLayout,并且有多个子路由组件 Home、About 和 Profile。其中,Profile 组件还包含更深层次的子路由 Settings 和 History。

主布局组件 MainLayout:

// MainLayout.jsx
import React from "react";
import { Link, Outlet } from 'react-router-dom'
const MainLayout = () => {
    return (
        <div>
            <nav>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/about">About</Link></li>
                    <li><Link to="/profile">Profile</Link></li>
                </ul>
            </nav>
            <main>
                <Outlet />
            </main>
        </div>
    );
};
export default MainLayout

MainLayout组件包含一个导航栏和一个主内容区域。<Outlet /> 组件用于渲染匹配的子路由组件。

子路由组件 Home 和 About

// Home.jsx
import React from 'react';
const Home = () => {
  return (
    <div>
      <h1>Home Page</h1>
      <p>Welcome to the home page!</p>
    </div>
  );
};
export default Home;
// About.jsx
import React from 'react';
const About = () => {
  return (
    <div>
      <h1>About Page</h1>
      <p>Welcome to the about page!</p>
    </div>
  );
};

export default About;

嵌套子路由组件 Profile

// Profile.jsx
import React from 'react';
import { Link, Outlet } from 'react-router-dom'
const Profile = () => {
    return (
      <div>
        <h1>Profile Page</h1>
        <nav>
          <ul>
            <li><Link to="settings">Settings</Link></li>
            <li><Link to="history">History</Link></li>
          </ul>
        </nav>
        <main>
          <Outlet />
        </main>
      </div>
    );
  };
export default Profile;

Profile组件包含一个导航栏和一个主内容区域。<Outlet /> 组件用于渲染匹配的子路由组件。

更深层次的子路由组件 ProfileSettings 和 ProfileHistory

// ProfileSettings.jsx
import React from 'react';
const ProfileSettings = () => {
    return (
      <div>
        <h2>Profile Settings</h2>
        <p>Manage your profile settings here.</p>
      </div>
    );
  };
  export default ProfileSettings
// ProfileHistory.jsx
import React from 'react';
const ProfileHistory = () => {
    return (
      <div>
        <h2>Profile History</h2>
        <p>View your profile history here.</p>
      </div>
    );
  };
  export default ProfileHistory

路由配置 App

import React, {lazy,Suspense} from "react"
import { Routes, Route } from "react-router-dom"
import MainLayout from './MainLayout.jsx'
import Home from "./Home.jsx"
import About from "./About.jsx"
import Profile from "./Profile.jsx"
const ProfileHistory = lazy(() => import('./ProfileHistory.jsx'))
const ProfileSettings = lazy(() => import('./ProfileSettings.jsx'))
export default function App() {
  return (
    <Routes>
      <Route path="/" element={<MainLayout />}>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="profile" element={<Profile />}>
          <Route path="settings" element={<Suspense><ProfileSettings /></Suspense>} />
          <Route path="history" element={<Suspense><ProfileHistory /></Suspense>} />
        </Route>
      </Route>
    </Routes>
  );
}
  • <Route path="/" element={<MainLayout />}> 定义了主布局组件 MainLayout。
  • <Route index element={<Home />} /> 定义了默认路由,当访问根路径 / 时,渲染 Home 组件。
  • <Route path="about" element={<About />} /> 定义了子路由 /about,当访问 /about 时,渲染 About 组件。
  • <Route path="profile" element={<Profile />}> 定义了子路由 /profile,当访问 /profile 时,渲染 Profile 组件。
  • <Route path="settings" element={<ProfileSettings />} /><Route path="history" element={<ProfileHistory />} /> 定义了更深层次的子路由 /profile/settings/profile/history
// main.jsx
import { createRoot } from 'react-dom/client' // 用于渲染页面的
import React from 'react' // 用于创建组件的
import { BrowserRouter as Router } from 'react-router-dom' // 引入路由
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
    <Router>
        <App />
    </Router>
)

2.gif

总结

  1. 子级路由的路径是相对于父级路由的路径的。
<Routes >
    <Route path="/" element={<MainLayout />}>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="profile" element={<Profile />}>
            <Route path="settings" element={<Suspense><ProfileSettings /></Suspense>} />
            <Route path="history" element={<Suspense><ProfileHistory /></Suspense>} />
        </Route>
    </Route>
</Routes >

path="profile"是相对于path="/"的,path="settings"是相对于path="profile"的,所以子级路由的路径/profile是相对于父级路由/的,子级路由的路径/profile/settings是相对于父级路由/profile的。

  1. 路由嵌套就是使用<Route>组件嵌套<Route>组件