vite+react18_约定式路由(import.meta.glob)

1,547 阅读2分钟

最近都是用 vite 写项目,记录下 vite 中的 react 约定式路由写法。好处相信大家使用过 umi 的都知道。直接上代码

先展示下目录结构

|——views
|    |——index.tsx // 函数组件
|    |——route.ts// 路由配置
|    |——phonelist   // 目录
|    |    |——index.tsx // 函数组件
|    |    |——route.ts // 路由配置
|    |——testReport   // 目录
|    |    |——index.tsx // 函数组件
|    |    |——route.ts // 路由配置
|    |——testingPhone   // 目录
|    |    |——index.tsx // 函数组件
|    |    |——route.ts // 路由配置
|    |    |——canvasStream   // 目录
|    |    |    |——index.tsx // 函数组件
|    |    |    |——route.ts // 路由配置

目录结构相对简单。

// views/route.ts
// 此文件相当于是路由元信息
export default {
    title: "layout", 
    menuOrder: 0,  
    navigate: '/phonelist'  // 设置重定向
}

最后是核心的约定式路由代码

// router/index.tsx
import { lazy, Suspense, useEffect } from "react";
import { Navigate, useNavigate, useRoutes } from "react-router-dom";


export default function RRouter() {

    // 配合路由懒加载执行
    const pagesString = import.meta.glob('../views/**/index.tsx')

    const pagesModule = import.meta.glob('../views/**/route.ts', {
        eager: true,  // 改成 具体模块导出的值,在 default 下面
        import: 'default'  // 配置默认就导出模块中的 default 属性
    })

    const routesInfo = Object.entries(pagesModule).map(([pagePath, config]) => {
        // 配置路径,如果没有就是 "/"
        const path: string = pagePath.replace("../views", "").replace("/route.ts", "") || "/"
        // 配置名字,如果没有就是 index
        const name = path.split("/").filter(Boolean).join("-") || "index"
        // 找到对应的组件
        const compPath = pagePath.replace("route.ts", "index.tsx")
        // @ts-ignore , 加入懒加载,套上 Suspense
        let Element = routerLazyLoadingFn(lazy(pagesString[compPath]))
        // 判断该页面需不需要登录鉴权
        // 🔴 当然,你可以根据项目实际情况,如除了 login 其余页面都需要登录才可以访问
        if (config.auth) Element = <AuthComponent>
            {Element}
        </AuthComponent>
        // 判断是否有重定向问题,这里不使用 index 是因为重定向更方便,效果相同
        // 请注意每个父路由都必须指定一个子路由去重定向,否则 Outlet 可能会显示不完全
        const element = config.navigate ? <Navigate to={config.navigate} /> : Element

        return {
            path,
            name,
            element,
            meta: config
        }
    })

    const routes = useRoutes(routesInfo)
    console.log(routesInfo);

    return routes
}

// @ts-ignore 
const AuthComponent = ({ children }) => {
    const navigation = useNavigate()

    if (localStorage.getItem('token')) {
        return children
    } else {
        useEffect(() => {
            navigation('/login')
        }, [])
    }
}

// 路由懒加载
const routerLazyLoadingFn = (Element: React.LazyExoticComponent<React.ComponentType<any>>) => <Suspense fallback={<>loading...</>}>
    <Element />
</Suspense>

本文只是对简单的重定向和懒加载以及鉴权做了基操。 gitee 地址:gitee.com/kkklbskl/dy… 有没有人知道 @ts-ignore 这里的类型填写什么,知道的说一下,谢谢