VUE动态路由和按钮的实现

cnblogs 2024-08-03 09:11:00 阅读 97

动态路由

动态菜单

<code>//通过循环组件完成动态菜单

<el-menu active-text-color="#ffd04b" background-color="#545c64" text-color="#fff"code>

:collapse="isCollapse" router default-active >code>

<el-menu-item index="99">code>

<img src="@/assets/logo.svg" width="18" />code>

<span >TMS用户管理系统</span>

</el-menu-item>

<el-menu-item index="/Main">code>

<el-icon>

<HomeFilled />

</el-icon>

<span>首页</span>

</el-menu-item>

<RecursiveMenuItem :apidto="apidto" />code>

<el-menu-item

@click="isCollapse = !isCollapse; isCollapse == true ? iconSwitch = 'Expand' : iconSwitch = 'Fold'">code>

<el-icon >

<component :is="iconSwitch"></component>code>

</el-icon>

<span>展开</span>

</el-menu-item>

</el-menu>

//子组件

<template v-for="item in props.apidto" key="item">code>

<el-sub-menu v-if="item.children && item.children.length > 0" :index="item.mName" :key="item">code>

<template #title>

<el-icon>

<component :is="item.mIcol" />code>

</el-icon>

<span>{{ item.mName }}</span>

</template>

<RecursiveMenuItem :apidto="item.children" /> <!-- 递归调用自身 -->code>

</el-sub-menu>

<el-menu-item v-else :index="item.roUrl">code>

<el-icon>

<component :is="item.mIcol" />code>

</el-icon>

<span>{{ item.mName }}</span>

</el-menu-item>

</template>

动态路由

import router from '@/router/index'

const modules = import.meta.glob('../views/**/*.vue')

//导航守卫+动态路由

//to是要跳转到的页面

//form是跳转前的页面

//next是不做任何阻拦允许跳转

router.beforeEach((to, from, next) => {

//pinia中获取用户登录状态

const CounterStore = useCounterStore();

//是否为登录状态,并且令牌不为空

if (CounterStore.isLogin && localStorage.getItem('token')) {

//如果路由是登录页面则跳转到主页

if (to.path === '/') {

next({

path: '/Main'

})

}

//不为登录页面

else {

//如果路由不存在则添加路由

if (to.name === undefined) {

const routes = JSON.parse(localStorage.getItem('apidto') as string);

addRoutesRecursively(routes);

next({ ...to, replace: true })

}

next();

}

}

//如果没有登录

else {

if (to.path === '/') {

next()

}

else {

next({

path: '/'

})

}

}

})

//递归获取用户

function addRoutesRecursively(routes: any[]) {

routes.forEach((route) => {

// 假设 route 可能包含 children 属性

if (route.children) {

// 递归调用自身来处理 children

addRoutesRecursively(route.children);

}

// 添加当前路由

else {

router.addRoute('Main', {

path: route.roUrl,

name: route.roName,

component: modules['../views' + route.moUrl] // 注意这里可能需要根据实际情况调整路径拼接方式

});

}

});

}

动态按钮

//pinia状态管理

import { useUserStore } from '../stores/User'

import type { Directive, DirectiveBinding } from "vue";

//权限按钮自定义事件

export const hasPerm: Directive = {

mounted(el: HTMLElement, binding: DirectiveBinding) {

// DOM绑定需要的按钮权限标识

const { value: requiredPerms } = binding;

if (requiredPerms) {

if (!hasAuth(requiredPerms)) {

el.parentNode && el.parentNode.removeChild(el);

}

} else {

throw new Error(

"你没有权限"

);

}

},

};

// 是否有权限

function hasAuth(

value: string | string[],

type: "button" | "role" = "button"//约束type只能为button或role,同时赋值默认值button

) {

//获取账号下的角色和权限

const userStore = useUserStore();

const { roles, perms } = userStore.users;

//「终极管理员」拥有所有的按钮权限

if (type === "button" && roles.includes("终极管理员")) {

return true;

}

//判断是否获取的是按钮权限,否则获取角色权限

const auths = type === "button" ? perms : roles;

//判断用户value是一堆角色还是单个角色

return typeof value === "string"

? auths.includes(value)//判断用户是否有这个权限

: auths.some((perm) => {

return value.includes(perm);//查询需要的权限是否拥有,可能是一个按钮可以有好几个角色访问

});

}

//Main中注册

//注册全局自定义指令

app.directive("hasPerm", hasPerm);



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。