vue3+vite+vue-router4.x实现动态添加路由

实现内容:

        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<Element>): 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()
  })
}

猜你喜欢

转载自blog.csdn.net/listener_life/article/details/130676767