基本的思路:
拿到路由数据
---------》
遍历路由数据通过router.addRoute一个个的添加,同时将路由数据缓存起来
-----------》
当页面刷新时,从缓存里拿出路由数据再重新添加,同时配合路由守卫来跳页面
当页面刷新后,即使你动态路由添加上去了,也能通过getRoutes拿到,但是刷新页面时的跳转会有问题,提示你该路由不存在之类的,这时要在路由守卫里通过router.push来跳转,这样就可以了(还是会提示错误但不影响使用)
第一次尝试做动态路由,如果有更好的方法实现,希望能评论告诉我!!!
在页面刷新后,即使添加路由成功后跳转也无效,这里卡了我一两天
路由页
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import layout from '@/views/layout/index.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/home/index'
},
{
path: '/home',
name: 'home',
component: layout,
meta: { title: '首页' },
redirect: '/home/homeIndex',
children: [
{
path: 'index',
name: 'homeIndex',
component: () => import('../views/home/index.vue'),
meta: { title: '首页' }
}
]
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
meta: { title: '登录' }
},
{
path: '/404',
name: '404',
component: () => import('../views/errorPage/404.vue'),
meta: { title: '404' }
}
];
const router = createRouter({
history: createWebHashHistory(),
routes
});
export default router;
路由守卫的js文件
import router from './index';
// 路由拦截
router.beforeEach((to, from, next) => {
const token = sessionStorage.getItem('token');
if (token) {
// 是否有该路径
if (to.matched.length > 0 || from.path !== '/') {
next();
} else {
// 防止页面刷新
if (from.path == '/' && to.matched.length <= 0) {
next(to.path);
} else {
next('/404');
}
}
} else {
// 反正让你去登录页
if (to.path == '/login') {
next();
} else {
next('/login');
}
}
});
login页面, store用的是Pinia
import { basicStore } from '@/store/basicData/index';
import { useRouter } from 'vue-router';
import { getCurrentInstance } from 'vue'
const router = useRouter();
const store = basicStore();
//const {proxy}:any = getCurrentInstance();//获取公共方法
//登录成功后
sessionStorage.setItem('token', 'afjskafjksafjsk');
store.AddDynamicRoute(); // 获取菜单
router.push({ name: 'homeIndex' });
main.ts页面
import pinia from './store';
import './router/permission'; // 路由守卫
const app = createApp(App);
app
.use(store)
.use(router)
.use(pinia)
.mount('#app')
app.vue页面,防止页面刷新动态路由消失
<script setup lang="ts">
import { basicStore } from './store/basicData/index';
const store = basicStore();
if (sessionStorage.getItem('token')) {
// 防止刷新页面后动态路由消失
store.AddDynamicRoute();
}
</script>
动态路由添加封装好的ts文件
import router from './index';
import testall from './test'; // 测试页面路由
// 所有的前端页面路由放到这来,然后通过这拿去注册路由
const routerlist = [...testall];
// 将后端菜单数据与前端路由匹配
const dealWithRoute = (use: Array<any>, all: Array<any> = routerlist) => {
const resul: Array<any> = [];
all.forEach((aa) => {
use.forEach((bb) => {
// 这匹配值根据后台传的值来定
if (bb.path == aa.name) {
if (bb.childer && bb.childer > 0) {
dealWithRoute(bb.childer, aa.childer);
}
resul.push(aa);
}
});
});
addDynamicRoute(resul);
};
// 添加动态路由,parent默认为home是首页最外层的路由name名
const addDynamicRoute = (useroute: Array<any>, parent = 'home') => {
for (let i = 0; i < useroute.length; i++) {
if (useroute[i].childer && useroute[i].childer.length > 0) {
router.addRoute(parent, useroute[i]);
// 递归添加动态路由
addDynamicRoute(useroute[i].childer, useroute[i].name);
} else {
router.addRoute(parent, useroute[i]);
}
}
};
export default dealWithRoute;
下载Pinia store >> basicData >> index.ts文件
import { defineStore } from 'pinia';
import dealWithRoute from '@/router/allRouter';
state: () => {
return {
MenuList: [] as any[], // 菜单数据
};
},
actions:{
/* 获取菜单,添加动态路由 */
AddDynamicRoute () {
let nowmenulist: Array<Object> = [];
if (this.MenuList?.length > 0) {
nowmenulist = this.MenuList;
} else {
// 通过接口拿菜单数据
nowmenulist = [
{
icon: 'Menu',
name: '控制台',
path: 'homeIndex'
},
{
icon: 'Stopwatch',
name: '移动端商城',
path: 'aa'
},
{
icon: 'Ticket',
name: '少时诵诗书',
path: 'bb',
childer: [
{
icon: 'ShoppingCart',
name: '的点点滴滴',
path: 'bb/dd'
}
]
},
{
icon: 'Reading',
name: '灌灌灌灌',
path: 'cc'
}
];
}
this.MenuList = nowmenulist;
dealWithRoute(nowmenulist); // 将拿到的菜单去匹配生成动态路由
return true
},
}