一、嵌套路由
1、基本介绍
-
默认情况下,子组件匹配成功,父组件的导航也会高亮,当 NavLink 上添加了 end 属性后,子组件匹配成功,父组件的导航不会高亮
-
<Outlet>组件用于,当前<Route>产生嵌套时,渲染其对应的后续子路由
2、演示
(1)page
- About 页面
tsx
export default function About() {
return <h3>About Content</h3>;
}
- Home 页面
tsx
import { NavLink, Outlet } from "react-router-dom";
export default function Home() {
function computedClassName({ isActive }) {
return isActive ? "my-item active" : "my-item";
}
return (
<div>
<h3>Home Content</h3>
<ul>
<li>
<NavLink className={computedClassName} to="news">
News
</NavLink>
</li>
<li>
<NavLink className={computedClassName} to="message">
Message
</NavLink>
</li>
</ul>
<Outlet />
</div>
);
}
- News 页面
tsx
export default function News() {
return (
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
);
}
- Message 页面
tsx
export default function Message() {
return (
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message3">message003</a>
</li>
</ul>
</div>
);
}
(2)route
- index.tsx
tsx
import About from "../pages/About";
import Home from "../pages/Home";
import News from "../pages/News";
import Message from "../pages/Message";
import { Navigate } from "react-router-dom";
export default [
{
path: "/about",
element: <About />,
},
{
path: "/home",
element: <Home />,
children: [
{
path: "news",
element: <News />,
},
{
path: "message",
element: <Message />,
},
],
},
{
path: "/",
element: <Navigate to="/about" />,
},
];
(3)main
- App 组件
tsx
import { NavLink, useRoutes } from "react-router-dom";
import routes from "./routes";
import "./App.css";
export default function App() {
const element = useRoutes(routes);
function computedClassName({ isActive }) {
return isActive ? "my-item active" : "my-item";
}
return (
<div>
<div>
<NavLink className={computedClassName} to="/about">
About
</NavLink>
<NavLink className={computedClassName} to="/home">
Home
</NavLink>
</div>
<div>{element}</div>
</div>
);
}
css
.my-item {
padding: 10px;
cursor: pointer;
}
.active {
color: red;
}
- index.tsx
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
二、路由传递参数
1、演示
(1)page
- Message 页面
tsx
import { useState } from "react";
import { NavLink, Outlet } from "react-router-dom";
export default function Message() {
const [messages] = useState([
{ id: "01", title: "消息 1" },
{ id: "02", title: "消息 2" },
{ id: "03", title: "消息 3" },
]);
return (
<div>
<h3>传递 params 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<NavLink to={`/message/detail/${item.id}/${item.title}`}>{item.title}</NavLink>
</li>
))}
</ul>
<h3>传递 search 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<NavLink to={`/message/news?id=${item.id}&title=${item.title}`}>{item.title}</NavLink>
</li>
))}
</ul>
<h3>传递 state 参数</h3>
<ul>
{messages.map((item) => (
<li key={item.id}>
<NavLink to="/message/tip" state={{ id: item.id, title: item.title }}>
{item.title}
</NavLink>
</li>
))}
</ul>
<Outlet />
</div>
);
}
- Detail 页面
tsx
import { useParams, useMatch } from "react-router-dom";
export default function Detail() {
const { id, title } = useParams();
// const x1 = useMatch("/message/detail/:id/:title");
// console.log(x1);
// const x2 = useMatch("/message/detail/:id");
// console.log(x2);
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
- News 页面
tsx
import { useSearchParams, useLocation } from "react-router-dom";
export default function News() {
const [search, setSearch] = useSearchParams();
const id = search.get("id");
const title = search.get("title");
const x = useLocation();
console.log(x);
return (
<div>
<button onClick={() => setSearch("id=04&title=消息 4")}>点击更新一下收到的 search 参数</button>
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
</div>
);
}
- Tip 页面
tsx
import { useLocation } from "react-router-dom";
export default function Tip() {
const {
state: { id, title },
} = useLocation();
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
(2)route
- index.tsx
tsx
import Message from "../pages/Message";
import Detail from "../pages/Detail";
import News from "../pages/News";
import Tip from "../pages/Tip";
import { Navigate } from "react-router-dom";
export default [
{
path: "/message",
element: <Message />,
children: [
{
path: "detail/:id/:title",
element: <Detail />,
},
{
path: "news",
element: <News />,
},
{
path: "tip",
element: <Tip />,
},
],
},
{
path: "/",
element: <Navigate to="/message" />,
},
];
(3)main
- App 组件
tsx
import { useRoutes } from "react-router-dom";
import routes from "./routes";
export default function App() {
const element = useRoutes(routes);
return <div>{element}</div>;
}
- main.tsx
tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
2、补充学习
-
useParams:用于返回当前匹配路由的 params 参数
-
useSearchParams:用于读取和修改当前位置的 URL 中的查询字符串,返回一个包含两个值的数组,内容分别为,当前的 search 参数、更新 search 的函数
-
useMatch:用于匹配当前 URL 是否与指定路径模式匹配,如果不匹配,返回 null
-
useLocation:用于返回当前 URL 的 location 对象,让开发者能够获取和监听当前路由信息