vue3 动态路由(权限显示、隐藏菜单)

1,517 阅读2分钟

登录的时候获取用户信息、用户绑定的角色信息、角色绑定的菜单和按钮信息缓存在本地,每一次路由守卫都会去缓存内校验菜单信息和按钮权限

添加状态管理(这里用的是pinia), 主要定义保存和获取方法

import { defineStore } from 'pinia';
import type { RouteRecordRaw } from 'vue-router';

export const useRoutesStore = defineStore('routes', {
  state: () => {
    return {
      routes: []
    };
  },
  getters: {
    getRoutes: (state) => {
      return state.routes;
    }
  },
  actions: {
    saveRoutes(routes: RouteRecordRaw[] | any) {
      this.routes = routes;
    }
  }
});

取状态管理器路由并动态生成导航菜单


import { useRoutesStore } from "@/store/modules/routes";

const store = useRoutesStore();

let menu: Array<menuProps> | any = ref([]);
onMounted(() => {
  const allRoutesProxy: RouteRecordRaw[] = toRaw(store.routes); // 获取状态管理器内的路由
  const allRoutes = allRoutesProxy[0].children; // 知识库的第一层路由是导航条,其他场景自己定义
  const all1LevelRoutes = allRoutes?.filter(
    (router: any) => router.meta.level === 0
  ); // 获取第一层路由
  const data: Array<menuProps> | any = all1LevelRoutes?.map((router: any) => {
    return {
      caption: router.meta.name,
      path: "/" + router.path,
      icon: router.meta.icon,
    };
  });

  menu.value = data;
});

在路由守卫内添加动态路由和往状态管理器塞值

const router = createRouter({
  history: createWebHashHistory(),
  routes: staticRoute, // 默认静态路由
});

router.beforeEach(
  async (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    const store = useRoutesStore();
    const names = staticRoute[0].children?.map((route: any) => route.meta.name); // 去重
    otherRoutes.forEach((route: any) => {
      if (!names?.includes(route.meta.name)) {
        router.addRoute("home", route); // 添加动态路由到路由中

        staticRoute[0].children?.push(route);
      }
    });
    store.saveRoutes(staticRoute); // 保存到状态管理器(用来渲染导航)
  }
);

获取权限然后过滤菜单进行状态管理器和动态路由的修改

1 router.removeRoute('home'); // 删除路由(参数是路由名称)。
2 需要判断系统路由有没有添加上路由,以及状态管理器内的路由存不存在。

动态路由添加后各种刷新、跳转空白问题修改

使用pinia持久化


import { createPinia } from 'pinia';

import piniaPluginPersist from 'pinia-plugin-persist';

  


const pinia = createPinia();

pinia.use(piniaPluginPersist);

  


export default pinia;

在动态路由生成后需要判断是否 to 的值丢失,丢失的情况下使用push方式跳转到指定页面

// 防止跳转导致页面空白
const jumpParams = window.location.href.split(/\?/);
const search = queryFormat(window.location.href);

if (to.matched.length == 0) {
  if (jumpParams.length >= 2) {
    // 带参数的路由直接刷新没有参数了,需要特殊处理添加详情
    router.push({
      path: to.path,
      query: search,
    });
  } else {
    router.push(to.path);
  }
} else {
  next();
}