Vite + Vue3 动态路由 - 踩坑记录

常见的几个问题

  • 刷新页面空白
    • addRoute 没有加载完成就访问 -> next() 改成 next({…to, replace: true})
    • 路由重名, 检查路由的name是否有重复
  • 路由守卫死循环
    • 添加一些条件, 比如: 判断是否已经获取到了路由数据
  • 刷新页面会跳转到404页面
    • 在动态路由添加完成后, 再添加404的路由
  • Vite 的组件懒加载
    const viteComponent = import.meta.glob("../views/**/*.vue")
    // ...
    component: viteComponent[`../views${item.path}.vue`]


贴一下路由守卫部分的代码

// 路由守卫
router.beforeEach((to, from, next) => {
    //在跳转路由之前,先清除所有的请求
    clearPending()

    // 判断是否登录
    if (to.path === "/login") {
        next()
    } else {
        let token = getToken()
        if (token && typeof token != "undefined") {
            // 如果vuex中没有路由数据,则获取路由数据
            if (store.state.menus.length === 0) {
                // 异步 确保路由已经添加完成 (貌似不需要)
                getRouters().then(() => {
                    next({
                        ...to, // 无限访问目标路由, 直到 addRoute() 添加完成
                        replace: true, // 本次操作后,不能通过浏览器后退按钮,返回前一个路由
                    })
                })
            } else {
                next()
            }
        } else {
            next("/login")
        }
    }
})

// 获取路由数据
const getRouters = () => {
    return new Promise((resolve) => {
        // 请求路由数据
        systemMenu.list().then((res) => {
            // 存入vuex
            store.dispatch("initMenu", res.data).then(() => {
                // 处理路由数据
                let data = handlerRouterDate(res.data)
                // 添加路由
                data.forEach((item: any) => {
                    router.addRoute("base", item)
                })

                // 在动态路由添加完成后, 才添加 404路由 否则会跳转到404页面
                router.addRoute("base", {
                    path: "/:w+",
                    name: "404Page",
                    component: () => import("@/views/404.vue"),
                })

                // 返回成功
                resolve(null)
            })
        })
    })
}

// 处理路由数据
const handlerRouterDate = (data: any) => {
    let routerData = <any>[]

    // 遍历路由数据
    data.forEach((item: any) => {
        if (item.children) {
            // 递归处理子路由
            let temp = handlerRouterDate(item.children)
            // 处理完成后,添加到同一级返回
            temp.forEach((sub: any) => {
                if (sub.router != "-") {
                    routerData.push(sub)
                }
            })
        }

        if (item.router != "-") {
            // 处理路由数据格式
            routerData.push(handlerRouterItem(item))
        }
    })

    return routerData
}

// 处理单个路由数据
const handlerRouterItem = (item: any) => {
    return {
        path: item.router,
        name: item.name,
        // webpack 用以下方式引入
        // component: () => import(`@/views${item.path}.vue`)
        // vite 需要以下方式引入
        component: viteComponent[`../views${item.path}.vue`],
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
啪嗒啪嗒啪嗒 (`・ω・´)つ_▃ <?php echo "PHP is the best language in the world!"; ?>
slowlyo
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 10

vite真的是很好用,我最近也在研究这个

2年前 评论
slowlyo (楼主) 2年前
longerspeech (作者) 2年前

有研究打包部署吗?

2年前 评论
slowlyo (楼主) 2年前

前台访问不到,JS加载 还是127.0.0.1:300

2年前 评论
slowlyo (楼主) 2年前

file vite 打包并没有 index.html 啊 :cry:

2年前 评论
slowlyo (楼主) 2年前

Vite 的组件懒加载搞了我两天时间,终于找到正确答案了 :+1: :+1: :+1:

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!