实现内容:
1.根据后台返回的菜单,前端实现动态添加路由;
2.解决刷新页面时,路由消失/页面空白的问题;
第一步:请求后台,返回菜单数据【内容如下】
// 后台返回的菜单数据
this.menuList = [
{ id: 1, path: '/home', name: '首页', icon: true, children: [], component: '/home/home' },
{ id: 12, path: '/pinia', name: 'pinia的使用', icon: true, children: [], component: '/pinia/pinia' },
{ id: 2, path: '/menu', name: '递归菜单页面', icon: true, children: [], component: '/recursion-menu/recursion-menu' },
{ id: 3, path: '/test', name: '测试', icon: true, children: [], component: '/test/test' },
{
id: 10,
path: '/permisson',
name: '权限管理',
icon: true,
children: [
{ id: '10-1', path: '/user', name: '用户管理', children: [], component: '/promission/user-manage' },
{ id: '10-2', path: '/role', name: '角色管理', children: [], component: '/promission/roles-manage' }
]
}
]
第二步:根据菜单数据,动态添加到路由信息中
1.静态路由【routes.ts文件】
import { RouteRecordRaw } from 'vue-router'
const Login = () => import('@/views/login/login.vue')
const Home = () => import('@/views/home/home.vue')
const Layout = () => import('@/layout/layout.vue')
const Page404 = () => import('@/views/error/page404.vue')
// 基础路由,不需要设置权限
export const basicRoutes:RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: Login
}, {
path: '/',
name: 'layout',
component: Layout,
meta: {
requiresAuth: true // 在这里设置,表示layout下边的子路由全部需要登录才能访问
},
redirect: '/home',
children: [
{
path: '/home',
name: 'home',
component: Home
}
]
}, {
path: '/:pathMatch(.*)',
name: 'page404',
component: Page404
}
]
2.基础路由信息【index.ts】
import { createRouter, createWebHashHistory } from 'vue-router'
import { basicRoutes } from '@/router/routes'
import { App } from 'vue'
import { setupRouterHooks } from '@/router/routerHooks'
export const router = createRouter({
history: createWebHashHistory(),
routes: basicRoutes
})
export function setupRouter (app: App): void {
// 路由钩子函数
setupRouterHooks()
app.use(router)
}
export default router
3.将数据动态添加到路由信息中【routerHooks.ts文件】
addRoutes(this.menuList) // 此处的menuList为上述中返回的数据
import { router } from '@/router/index'
import type { MenuItem } from '@/pinia/modules/menu'
import { RouteRecordRaw } from 'vue-router'
// vue3 + vite中的动态引入组件的方法
const loadView = import.meta.glob('../views/**/*.vue')
// 动态添加路由
export function addRoutes (menu: MenuItem[]) {
menu.forEach(e => {
// 只将页面信息添加到路由中
if (!e.children || e.children.length === 0) {
router.addRoute('layout', { name: e.path.slice(1), path: e.path, meta: { title: e.name }, component: loadView[`../views${e.component}.vue`] })
} else {
addRoutes(e.children)
}
})
}
第三步:添加路由钩子,解决页面刷新,路由消失的问题【routerHelper.ts】
import { router } from '@/router/index'
import nprpgreee from 'nprogress'
import 'nprogress/nprogress.css'
import { useMenuStoreWithOut } from '@/pinia/modules/menu'
const menuStore = useMenuStoreWithOut()
export function setupRouterHooks () {
router.beforeEach((to, from, next) => {
nprpgreee.start() // 开始加载进度条
if (to.path === '/login') {
next()
} else {
// 页面刷新时,重新加载路由
if (menuStore.menuList.length === 0) {
menuStore.setMenuList()
next({ path: to.path })
// next({ ...to, replace: true }) //此方法不生效
} else {
next()
}
}
})
router.afterEach(() => {
nprpgreee.done()
})
}