Vue3 动态路由实现的一种方法

动态路由

目的: 根据服务器传回来的数据动态的注册路由信息,登录用户的角色不同生成的菜单不同
使用插件做动态路由的好处: 路由页面增加或者减少时,只需要增加或减少相关的路由文件,不需要再修改代码

  • 服务器返回的信息格式中需要有路由信息"route": "/home/user",,说明该角色有访问"/home/user"路由的权限
// 角色权限
{
 	{
	     "id": 1,
	     "route": "/home/user",
	     "name": "用户管理",
	},
	{
	     "id": 2,
	     "route": "/home/department",
	     "name": "部门管理",
	},
	{
	     "id": 3,
	     "route": "/home/menu",
	     "name": "菜单管理",
	},
	{
	     "id": 4,
	     "route": "/home/role",
	     "name": "角色管理",
	}
}

1. 全局安装coderwhy插件

pnpm i coderwhy -g
// 检查是否安装成功
coderwhy --version
// 1.2.2

2. coderwhy插件使用

在这里插入图片描述

  • 示例
coderwhy add3page_setup index -d src/views/main/system/department
  • 执行命令后会自动生成两个文件
    1. 在命令中指定的目录src/views/main/system/department生成.vue文件
      在这里插入图片描述

    2. 同时自动在router文件夹下生成相同路径、相同文件名的.ts文件
      在这里插入图片描述

  • 组件:index.vue
<template>
  <div class="index">
    <h2>index</h2>
  </div>
</template>

<script setup lang="ts" name="index"></script>

<style scoped>
.index {
}
</style>
  • 路由文件:index.ts
const index = () => import('@/views/main/system/department/index.vue')
export default {
  path: '/main/system/department',
  name: 'index',	// 这里需要修改为department
  component: index,
  children: []
}
  1. 使用插件将所有的路由文件和组件文件全部创建好
    在这里插入图片描述

3. 把所有文件中的路由导出,组成一个数组

import.meta.glob 官网介绍

import type { RouteRecordRaw } from 'vue-router'

function getAllMainRoutes(): RouteRecordRaw[] {
  // 1. 获取所有路由文件,每一个文件对应一个路由,一个文件是一个对象
  const modules: Record<string, any> = import.meta.glob('@/router/main/**/*.ts', {
    eager: true,
    import: 'default'
  })
  // 2.  把文件中中的路由信息放入数组中
  let allRoutes: RouteRecordRaw[] = []
  allRoutes = Object.values(modules)
  return allRoutes
}
  • allRoutes:是所有路由的集合,它是从文件生成的,以后只需要在相应的位置添加vue组件对应的路由文件,这个方法就会自动生成路由的集合

5. 动态生成路由

allRoutes与服务器返回的 角色的路由信息 进行比对,就能生成该角色对应的路由表

// roleMenu:服务器返回的角色权限
function mainAddChildrenRoutes(roleMenu: []): RouteRecordRaw[] {
  const routes: RouteRecordRaw[] = []
  const roleRoutes = getAllMainRoutes()	// 所有的路由
  // 3. 遍历菜单信息,把菜单信息中的url与路由信息中的path进行匹配
  for (const menu of roleMenu) {
    const route = roleRoutes.find((item) => item.path === menu.route)
    if (route) routes.push(route) 
 }
  return routes	// 返回结果是动态路由,下一步只需要将路由加载到路由器中
}

6. 使用动态路由后刷新白屏

  • 刷新页面会导致加载到路由器的动态路由丢失,需要在刷新的同时将动态路由重新加载到路由器
  1. 从登录页面进入时加载一次动态路由(登录的请求完成后,页面跳转之前)
  2. 在pinia加载后,route加载前重新加载一次动态路由到路由器
  • pinia改写
import { createPinia } from 'pinia'
import type { App } from 'vue'
import { useLoginStore } from '@/stores/login'

function setupPinia(app: App<Element>) {
  const pinia = createPinia()
  app.use(pinia)	// 加载pinia
  // 初始化角色菜单,加载路由到路由器
  const loginStore = useLoginStore()
  loginStore.setRoleMenu()
}
export default setupPinia


// main.js
setupPinia(app)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值