[email protected](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>
    );
}

效果:


以上。

相关推荐
BillKu1 小时前
Vue3 Element Plus 对话框加载实现
javascript·vue.js·elementui
郝YH是人间理想1 小时前
系统架构设计师案例分析题——web篇
前端·软件工程
Evaporator Core1 小时前
深入探索:Core Web Vitals 进阶优化与新兴指标
前端·windows
初遇你时动了情2 小时前
html js 原生实现web组件、web公共组件、template模版插槽
前端·javascript·html
QQ2740287562 小时前
Soundness Gitpod 部署教程
linux·运维·服务器·前端·chrome·web3
前端小崔2 小时前
从零开始学习three.js(18):一文详解three.js中的着色器Shader
前端·javascript·学习·3d·webgl·数据可视化·着色器
哎呦你好2 小时前
HTML 表格与div深度解析区别及常见误区
前端·html
运维@小兵2 小时前
vue配置子路由,实现点击左侧菜单,内容区域显示不同的内容
前端·javascript·vue.js
koiy.cc3 小时前
记录:echarts实现tooltip的某个数据常显和恢复
前端·echarts
一只专注api接口开发的技术猿3 小时前
企业级电商数据对接:1688 商品详情 API 接口开发与优化实践
大数据·前端·爬虫