哪个网站做调查问卷赚钱,阳江市问政平台举报,网络推广和网络运营,服装搭配网站建设策划书1.动态获取权限并根据获取权限转换成相对应的router
根据请求获取菜单数据#xff0c;对菜单数据进行转换#xff0c;分别进行下面几步#xff1a;
/*** 组件地址前加斜杠处理*/
export function addSlashToRouteComponent(routeList: AppRouteRecordRaw[]) {routeList.fo…1.动态获取权限并根据获取权限转换成相对应的router
根据请求获取菜单数据对菜单数据进行转换分别进行下面几步
/*** 组件地址前加斜杠处理*/
export function addSlashToRouteComponent(routeList: AppRouteRecordRaw[]) {routeList.forEach((route) {const component route.component as string;if (component) {const layoutFound LayoutMap.get(component);if (!layoutFound) {route.component component.startsWith(/) ? component : /${component};}}route.children addSlashToRouteComponent(route.children);});return routeList;
}
利用import函数通配符引入匹配的所有vue页面,如下
const LayoutMap new Mapstring, () Promisetypeof import(*.vue)();
以及const dynamicViewsModules import.meta.glob(../../views/**/*.{vue,tsx});
该map会生成一个以页面路径为key的带有import动态引入的方法为值的对象这是可以通过处理key字符串通过获取的菜单列表匹配对应的path最终的component 就等于dynamicViewsModules[path]
function dynamicImport(dynamicViewsModules: Recordstring, () PromiseRecordable, component: string) {const keys Object.keys(dynamicViewsModules);const matchKeys keys.filter((key) {const k key.replace(../../views, );const startFlag component.startsWith(/);const endFlag component.endsWith(.vue) || component.endsWith(.tsx);const startIndex startFlag ? 0 : 1;const lastIndex endFlag ? k.length : k.lastIndexOf(.);return k.substring(startIndex, lastIndex) component;});if (matchKeys?.length 1) {const matchKey matchKeys[0];return dynamicViewsModules[matchKey];} else if (matchKeys?.length 1) {console.log(Please do not create .vue and .TSX files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure);return;}
}
处理后最终返回的数据就是生成router树状结构
2.动态添加路由addRoute
const menuRecordRoutes: RouteRecordRaw[] Object.entries(menuRoutes).map(([, config]) config).sort((a: any, b: any) a.order - b.order) as RouteRecordRaw[];
menuRecordRoutes.forEach((route) {router.addRoute(route);});
这里有个值得注意的地方如果是该菜单列表下有多个子菜单需要将子菜单也添加进去如
menuRecordRoutes.forEach((route) {router.addRoute(route);if (route?.children?.length) {route.children.forEach((child) {child.name route.name?.toString() - child.name?.toString();if (route.name) {router.addRoute(route.name, child);}});}});
上图中后面一个router.addRoute是针对每个子菜单进行router添加并且这里还有一个坑
如果不同的菜单下的子菜单的name属性是一样的话 这里可能会把前面一个添加的子菜单给覆盖了因为router中的name 属性是唯一的所以这里对子菜单的name做了一个拼接将父菜单名称和子菜单名称拼接到一起作为子菜单的新名称。另外这个name属性非常重要如果name属性中含有特殊符号如namedetailid页面中如果使用了类似这样的页面跳转router.push({ name: detail, params: { id: row.id } }); 则会导致路由不匹配的问题
3.自定义指令控制按钮显隐
//main.ts中引用
const app createApp(App);
// 全局注册 自定义指令(directive)
setupDirective(app);
import type { App } from vue;import { hasPerm } from ./permission;// 全局注册 directive
export function setupDirective(app: AppElement) {// 使 v-hasPerm 在所有组件中都可用app.directive(hasPerm, hasPerm);
}//自定义指令的自定义方法
export const hasPerm: Directive {mounted(el: HTMLElement, binding: DirectiveBinding) {// 「超级管理员」拥有所有的按钮权限const { authList } useUserStoreHook();const { value } binding;let result false;if (authList.length value) {if (Array.isArray(value)) {result value.every((ele) authList.includes(ele));} else {result authList.includes(value);}}if (!result) {el.parentNode el.parentNode.removeChild(el);}return result;},
};
页面中使用
el-button v-hasPerm[xxx] :iconDelete sizesmall text typeprimary删 除/el-button
至此动态菜单和按钮权限功能完成