Vue3+Vite实现动态路由的详细实例代码
作者:祥武的哥哥 时间:2023-07-02 16:58:37
项目基本目录
1.首先定义初始默认的路由routes(router.js文件),vue文件使用import引入可以按需加载
import {
createRouter,
createWebHashHistory
} from "vue-router";
import store from '../store/index.js'
const routes = [{
path: "/login",
component: () => import("../view/Login/index.vue"),
children: [],
meta: {
title: '登录页',
hideMenu: true, //加入hideMenu属性,不展示在侧边栏
},
name: "Login",
},
{
path: "/",
component: () => import("../view/Home/index.vue"),
meta: {
keepalive: true,
title: "主页",
},
name: 'Home',
// hideMenu: true,//不展示在侧边栏
children: [],
redirect: '/index'
},
]
2.在store的login.js模块写入调用后端数据的函数(写在vuex的action对象中,方便全局异步调用)
Vuex 允许我们将 store 分割成模块(module),比如登录模块,项目各个业务不相关的模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块(具体可以看主页另一篇博客)
3.执行addRoutes函数获取动态路由 (在router.js文件,点击登录成功后,在全局路由守卫去判断是否登录成功,再调用addRoutes函数)
(1)全局路由守卫逻辑具体可看注释,好处是进入项目之后,刷新页面路由守卫会拦截跳转,可以重新执行addRoutes()获取路由,先获取动态路由,再执行跳转,不然页面会报本地路由找不到(一个小坑)
(代码如下)
router.beforeEach(async (to, from, next) => { //路由守卫
if (store.state.login.token) { //存在token
if (to.path == '/login') { //存在token,如果想跳转到登录页,默认有token跳转进项目首页
next({
path: '/'
})
} else {
//如果存在token,跳转进项目页面,则判断当前后端返回的路由有无长度
//或者有无即将跳转路由的name
if (store.getters['login/getRoutes'].length || to.name != null) {
next() //有的话直接跳转
} else { //不满足条件的话,重新请求后端动态路由数据
await addRoutes(); //addRoutes()必须加入await!!!!等待逻辑执行完毕获取路由
// 如果 addRoute 未完成,路由守卫会一层一层的执行执行,不加next()可能导致卡死!
//直到 addRoute 完成,找到对应的路由
next({
...to,
replace: true
})
}
}
} else {
if (to.path == '/login') {
next()
} else {
next('/login')
}
}
})
后端返回的格式
(2)(重点在这,前面的步骤都可以不是重点)Vite使用import.meta.glob动态导入view文件夹所有前端页面,并调用addRoutes()函数执行获取动态路由数据并做处理(代码如下),主要作用是替换掉后端返回的component格式,再addRoute进路由表(看不懂的可以看代码注释或者可以搬进自己的项目打印看看每一步获取的数据)
let asyncRoutes = [] //定义数组接收后端返回的路由
const routeAllPathToCompMap =import.meta.glob(`../view/**/*.vue`);
//**为通配符,vite不支持require导入方式,故用import.meta.glob(vite动态导入)
/*import.meta.glob
* 该方法匹配到的文件默认是懒加载,通过动态导入实现,构建时会分离独立的 chunk,是异步导入,返回的是 Promise
* /*import.meta.globEager
* 该方法是直接导入所有模块,并且是同步导入,返回结果直接通过 for...in循环就可以操作
*/
async function addRoutes() {
await store.dispatch('login/getNewRoutes').then((res) => { //获取后端返回的动态路由
if (res.data && res.data.length) {
// let homeRouteChildren = [];
asyncRoutes = res.data;
/*
* 1。拿到处理完毕home的children,最终替换掉原来的children,给菜单渲染提供支持
* 2.通过递归,调用router.addRoute,把每一项route插到对应的父route下
*/
//服务端配置了路由,但前端还没添加对应文件的路由列表,内容是路由的component值(服务端的)
// const unForList = ['']
const homeChildren = routes[1].children;
const dfs = (parentRouteName = 'Home', asyncRoutes = [], originRouteChildren = []) => {
if (!Array.isArray(asyncRoutes)) return [];
asyncRoutes.forEach(route => {
// if (unForList.includes(route.component)) return;
/**后端返回来的路由component是字符串,如component: "view/Index/index.vue",
* 前端需要把component: "view/Index/index.vue" 转化为组件对象
* component:() => import("/src/view/Index/index.vue")
**/
route.component = routeAllPathToCompMap[`../${route.component}`];
// route.component = () => import(`../${route.component}`);
const routeChildren = route.children;
router.addRoute(parentRouteName, route);
route.children = dfs(route.name, routeChildren)
originRouteChildren.push(route)
})
return originRouteChildren
}
// homeRouteChildren = dfs(asyncRoutes)
dfs('Home', asyncRoutes, homeChildren)
}
});
}
最终转化完成,路由数据格式如下
动态路由到此完成
来源:https://blog.csdn.net/weixin_42804664/article/details/124443667
标签:vue3,vite,动态路由
0
投稿
猜你喜欢
django搭建项目配置环境和创建表过程详解
2022-10-26 19:03:25
SQLserver查询数据类型为ntext是空或NULL值的方法
2024-01-24 18:40:52
Go语言实现互斥锁、随机数、time、List
2024-04-25 15:11:24
CSS网页布局避免滥用DIV元素
2011-03-30 12:34:00
sqlserver2005 TSql新功能学习总结(数据类型篇)
2024-01-28 10:46:07
使用Pycharm(Python工具)新建项目及创建Python文件的教程
2022-06-07 11:43:52
python入门游戏之井字棋实例代码
2021-07-13 20:26:48
Python使用jpype模块调用jar包过程解析
2023-04-12 03:07:12
python多进程读图提取特征存npy
2022-09-05 11:38:06
Vite版本更新检查实现页面自动刷新的解决思路
2024-04-27 16:17:07
oracle快速删除重复的记录
2010-07-23 13:03:00
基于Python中求和函数sum的用法详解
2022-12-05 23:26:18
Python3使用 GitLab API 进行批量合并分支
2023-05-26 08:38:53
举例讲解Python中的Null模式与桥接模式编程
2021-10-05 09:06:34
Java API学习教程之正则表达式详解
2023-10-23 05:28:21
.Net Core导入千万级数据至Mysql的步骤
2024-01-19 17:05:59
python中hasattr()、getattr()、setattr()函数的使用
2022-12-11 20:14:27
Django CBV类的用法详解
2022-11-24 20:33:43
打败 IE 的葵花宝典:CSS Bug Table
2010-08-03 12:30:00
浅析JavaScript中的隐式类型转换
2024-04-29 13:38:22