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


    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>
    

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

    • news 相关的3个路由页面是相互独立的,只是逻辑上有关系。
    • goods 路由的写法,需要在 GoodsView 组件内也使用 RouterView 才能访问到路由 goods/detailgoods/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.childrenRootRoute.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>
        );
    }
    

    效果:

    在这里插入图片描述


    以上。

  • 相关阅读:
    ESP32——WEB服务程序测试(基于官方示例restful_server)
    UE5学习笔记 判断物体是否在相机视野内
    three.js检测物体是否包含某物体或与某物体相交
    基于激励的需求响应计划下弹性微电网的短期可靠性和经济性评估(Matlab代码实现)
    hdlbits系列verilog解答(7458芯片)-10
    常用类15:Math类
    JoySSL证书买二送一买三送二特别活动
    leetcode 46. 全排列
    Spring Boot Logging 配置
    linux下的io_uring和windows下的overlapped均可实现异步I/O,有什么异同?
  • 原文地址:https://blog.csdn.net/qq_40147756/article/details/139883480