目录
- 1,vue-router
- 2,React 模拟实现
1,vue-router
vue 的路由配置文件,
// src/router/index.ts
const routes = [
{
path: "/news",
children: [
{ path: "", component: NewsView },
{ path: "detail", component: NewsDetail },
{ path: "search", component: NewsSearch },
],
},
{
path: "/goods",
component: GoodsView,
children: [
{ path: "detail", component: GoodsDetail },
{ path: "search", component: GoodsSearch },
],
},
{ path: "/", component: HomeView },
];
在 App.vue
中使用 RouterView
即可渲染匹配到的路由:
<template>
<RouterView></RouterView>
</template>
另外,注意 news
和 goods
路由的区别:
news
相关的3个路由页面是相互独立的,只是逻辑上有关系。goods
路由的写法,需要在GoodsView
组件内也使用RouterView
才能访问到路由goods/detail
和goods/search
对应的页面。
<template>
<div>goods主页面</div>
<RouterView></RouterView>
</template>
2,React 模拟实现
使用和 vue 相同的配置文件,routeConfig.js
App.jsx
import { BrowserRouter as Router, Switch, Link } from "react-router-dom";
import RootRoute from "./RootRoute";
export default function App() {
return (
<Router>
<Link to="/">首页</Link>
<Link to="/news">新闻页</Link>
<Link to="/goods">商品页</Link>
<Switch>
<RootRoute></RootRoute>
</Switch>
</Router>
);
}
关键实现:RootRoute.js
import React from "react";
import { Route } from "react-router-dom";
import routeConfig from "./routeConfig";
export default function RootRoute() {
return getRoutes(routeConfig, "");
}
function getRoutes(routes, basePath) {
if (!Array.isArray(routes)) {
return null;
}
return routes.map((route) => {
const { path, component: Component, children, ...rest } = route;
const newPath = `${basePath}${path}`;
// 适配 news 路由的方式
if (Component) {
return (
<Route
key={newPath}
path={newPath}
exact={["", "/"].includes(path)}
{...rest}
render={(values) => {
return <Component {...values}>{getRoutes(children, newPath)}</Component>;
}}
></Route>
);
} else {
return getRoutes(children, newPath);
}
});
}
News.jsx
export default function News() {
return (
<div>
<div>News页面</div>
<Link to="/news/detail">详情</Link>
<Link to="/news/search">查询</Link>
</div>
);
}
Goods.jsx,其中 props.children
是 RootRoute.js 遍历子路由渲染出对应的 <Route>
组件。
export default function Goods(props) {
return (
<div>
<div>Goods页面</div>
<Link to="/goods/detail">goods详情</Link>
<Link to="/goods/search">goods查询</Link>
<div>{props.children}</div>
</div>
);
}
效果:
以上。