找回密码
 立即注册
首页 业界区 业界 VUE动态路由和按钮的实现

VUE动态路由和按钮的实现

捐催制 2025-6-6 11:11:53
动态路由

动态菜单
  1. //通过循环组件完成动态菜单
  2. <el-menu active-text-color="#ffd04b" background-color="#545c64"  text-color="#fff"
  3.         :collapse="isCollapse" router default-active >
  4.         <el-menu-item index="99">
  5.             <img src="https://www.cnblogs.com/@/assets/logo.svg" width="18" />
  6.             TMS用户管理系统
  7.         </el-menu-item>
  8.         <el-menu-item index="/Main">
  9.             <el-icon>
  10.                 <HomeFilled />
  11.             </el-icon>
  12.             首页
  13.         </el-menu-item>
  14.         <RecursiveMenuItem :apidto="apidto" />
  15.         <el-menu-item
  16.             @click="isCollapse = !isCollapse; isCollapse == true ? iconSwitch = 'Expand' : iconSwitch = 'Fold'">
  17.             <el-icon >
  18.                 <component :is="iconSwitch"></component>
  19.             </el-icon>
  20.             展开
  21.         </el-menu-item>
  22.     </el-menu>
  23. //子组件
  24. <template v-for="item in props.apidto" key="item">
  25.         <el-sub-menu v-if="item.children && item.children.length > 0" :index="item.mName" :key="item">
  26.             <template #title>
  27.                 <el-icon>
  28.                     <component :is="item.mIcol" />
  29.                 </el-icon>
  30.                 {{ item.mName }}
  31.             </template>
  32.             <RecursiveMenuItem :apidto="item.children" />
  33.         </el-sub-menu>
  34.         <el-menu-item v-else :index="item.roUrl">
  35.             <el-icon>
  36.                 <component :is="item.mIcol" />
  37.             </el-icon>
  38.             {{ item.mName }}
  39.         </el-menu-item>
  40.     </template>
复制代码
动态路由
  1. import router from '@/router/index'
  2. const modules = import.meta.glob('../views/**/*.vue')
  3. //导航守卫+动态路由
  4. //to是要跳转到的页面
  5. //form是跳转前的页面
  6. //next是不做任何阻拦允许跳转
  7. router.beforeEach((to, from, next) => {
  8.     //pinia中获取用户登录状态
  9.     const CounterStore = useCounterStore();
  10.     //是否为登录状态,并且令牌不为空
  11.     if (CounterStore.isLogin && localStorage.getItem('token')) {
  12.         //如果路由是登录页面则跳转到主页
  13.         if (to.path === '/') {
  14.             next({
  15.                 path: '/Main'
  16.             })
  17.         }
  18.         //不为登录页面
  19.         else {
  20.             //如果路由不存在则添加路由
  21.             if (to.name === undefined) {
  22.                 const routes = JSON.parse(localStorage.getItem('apidto') as string);
  23.                 addRoutesRecursively(routes);
  24.                 next({ ...to, replace: true })
  25.             }
  26.             next();
  27.         }
  28.     }
  29.     //如果没有登录
  30.     else {
  31.         if (to.path === '/') {
  32.             next()
  33.         }
  34.         else {
  35.             next({
  36.                 path: '/'
  37.             })
  38.         }
  39.     }
  40. })
  41. //递归获取用户
  42. function addRoutesRecursively(routes: any[]) {
  43.     routes.forEach((route) => {
  44.         // 假设 route 可能包含 children 属性  
  45.         if (route.children) {
  46.             // 递归调用自身来处理 children  
  47.             addRoutesRecursively(route.children);
  48.         }
  49.         // 添加当前路由
  50.         else {
  51.             router.addRoute('Main', {
  52.                 path: route.roUrl,
  53.                 name: route.roName,
  54.                 component: modules['../views' + route.moUrl] // 注意这里可能需要根据实际情况调整路径拼接方式  
  55.             });
  56.         }
  57.     });
  58. }
复制代码
动态按钮
  1. //pinia状态管理       
  2. import { useUserStore } from '../stores/User'
  3. import type { Directive, DirectiveBinding } from "vue";
  4. //权限按钮自定义事件
  5. export const hasPerm: Directive = {
  6.     mounted(el: HTMLElement, binding: DirectiveBinding) {
  7.         // DOM绑定需要的按钮权限标识
  8.         const { value: requiredPerms } = binding;
  9.         if (requiredPerms) {
  10.             if (!hasAuth(requiredPerms)) {
  11.                 el.parentNode && el.parentNode.removeChild(el);
  12.             }
  13.         } else {
  14.             throw new Error(
  15.                 "你没有权限"
  16.             );
  17.         }
  18.     },
  19. };
  20. // 是否有权限
  21. function hasAuth(
  22.     value: string | string[],
  23.     type: "button" | "role" = "button"//约束type只能为button或role,同时赋值默认值button
  24. ) {
  25.     //获取账号下的角色和权限
  26.     const userStore = useUserStore();
  27.     const { roles, perms } = userStore.users;
  28.     //「终极管理员」拥有所有的按钮权限
  29.     if (type === "button" && roles.includes("终极管理员")) {
  30.         return true;
  31.     }
  32.     //判断是否获取的是按钮权限,否则获取角色权限
  33.     const auths = type === "button" ? perms : roles;
  34.     //判断用户value是一堆角色还是单个角色
  35.     return typeof value === "string"
  36.         ? auths.includes(value)//判断用户是否有这个权限
  37.         : auths.some((perm) => {
  38.             return value.includes(perm);//查询需要的权限是否拥有,可能是一个按钮可以有好几个角色访问
  39.         });
  40. }
  41. //Main中注册
  42. //注册全局自定义指令
  43. app.directive("hasPerm", hasPerm);
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
1.jpg

相关推荐

您需要登录后才可以回帖 登录 | 立即注册