React@16.x(40)路由v5.x(5)常见应用场景(2)- 实现类似 vue 的路由模式

目录

1,vue-router

vue 的路由配置文件,

js 复制代码
// 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 即可渲染匹配到的路由:

html 复制代码
<template>
    <RouterView></RouterView>
</template>

另外,注意 newsgoods 路由的区别:

  • news 相关的3个路由页面是相互独立的,只是逻辑上有关系。
  • goods 路由的写法,需要在 GoodsView 组件内也使用 RouterView 才能访问到路由 goods/detailgoods/search 对应的页面。
html 复制代码
<template>
	<div>goods主页面</div>
    <RouterView></RouterView>
</template>

2,React 模拟实现

使用和 vue 相同的配置文件routeConfig.js

App.jsx

js 复制代码
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

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

js 复制代码
export default function News() {
    return (
        <div>
            <div>News页面</div>
            <Link to="/news/detail">详情</Link>
            <Link to="/news/search">查询</Link>
        </div>
    );
}

Goods.jsx ,其中 props.childrenRootRoute.js 遍历子路由渲染出对应的 <Route> 组件。

js 复制代码
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>
    );
}

效果:


以上。

相关推荐
shmily麻瓜小菜鸡26 分钟前
JS/TS 易踩坑知识点 — 模块化与工程化类
开发语言·javascript·ecmascript
萧鼎39 分钟前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi
IT_陈寒1 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
计算机魔术师2 小时前
5000亿估值冲刺科创板,DeepSeek 为何急着上市?
前端
我血条子呢2 小时前
前端解析word方案
前端·word
kyriewen2 小时前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
申行2 小时前
Vue 3 + DYMO Connect Framework 实战:从标签模板到打印服务的完整实现
前端
两只羊ovo2 小时前
Vue 3 + DeepSeek 流式输出实战:从“干等”到“打字机”体验
前端·vue.js
Yeyu2 小时前
车载多 App 同屏渲染(二):SurfaceControlViewHost 跨进程
前端
樊小肆2 小时前
离谱,每轮请求 25% 的 token,竟在重发模型想完就扔的内心独白
前端·人工智能·agent