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>
    );
}

效果:


以上。

相关推荐
WooaiJava1 小时前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
LYFlied1 小时前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
爱喝白开水a1 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied1 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌411 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
WeiXiao_Hyy2 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡2 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone2 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09013 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农3 小时前
Vue 2.3
前端·javascript·vue.js