shayloyuki

科技是第一生产力

 

若依菜单改造(三):根据不同项目,加载动态菜单

需求

切换项目,加载不同的菜单项。

效果:

image

思路

实现方式

加载的菜单项数据不同,那么要请求接口,根据返回数据渲染菜单。

因此,路由不能通过 菜单管理 方式添加,也不能在 router.js 中写死,只能用 router.addRoutes() 动态添加。

添加时机

全局监听项目id,切换项目时,触发 router.addRoutes()

触发方式:Vuex

路由池

要往侧边栏添加菜单项,即添加到 sidebarRouters 中。

代码

App.vue 全局监听 projectId

src/App.vue
import store from "./store";
  computed: {
    projectId() {
      return this.$route.query.projectId;
    },
  },
  watch: {
    // 全局监听项目id
    projectId: {
      handler(newVal, oldVal) {
        if (!newVal || newVal == oldVal) return;
        // 请求项目菜单路由
        store.dispatch("GeneProAppRoutes", newVal);
      },
      immediate: true,
    },
  },

Vuex 中:请求接口、生成路由

src/store/modules/permission.js
import { queryProApps } from "@/api/app_ele.js";

mutations: {
    // 在原侧边栏路由的基础上更新路由
    UPDATE_SIDEBAR_ROUTES: (state, [routes, insertIndex]) => {
      if (!insertIndex) {
        state.sidebarRouters = state.sidebarRouters.concat(routes);
      } else {
        let arr = [...state.sidebarRouters];
        arr.splice(insertIndex, 0, ...routes);
        state.sidebarRouters = arr;
      }
    },
    // 移除某个侧边栏路由
    REMOVE_SIDEBAR_ROUTES: (state, routePath) => {
      state.sidebarRouters = state.sidebarRouters.filter(
        (item) => item.path !== routePath
      );
    },
}

actions: {
    // 动态路由
    GeneProAppRoutes({ commit }, projectId) {
      return new Promise((resolve) => {
        // 根据项目id生成项目库应用路由列表
        queryProApps({ projectId }).then((res) => {
          let proAppRoutes = res.data.map((ele) => {
            let obj = {
              component: () =>
                import(
                  /* webpackChunkName: 'appEle' */ "@/views/data-manage/app-ele/index.vue"
                ),
              name: "AppEle",
              meta: {
                icon: "chart",
              },
            };
            obj.path = `appEle/${ele.applyId}`;
            obj.meta.title = ele.applyName;
            return obj;
          });

          let newRoutes = [
            {
              path: "/project/data",
              component: Layout,
              redirect: "noRedirect",
              meta: {
                menuTitle: `项目空间`,
                title: `数据管理`,
                icon: "documentation",
              },
              alwaysShow: true,
            },
          ];
          newRoutes[0].children = proAppRoutes;
          // router.addRoutes(this.filterDynamicRoutes(newRoutes)) // 后续若加入 permissions 权限校验,则使用此行代码
          router.addRoutes(newRoutes);
          // 在原路由的基础上清除、更新
          commit("REMOVE_SIDEBAR_ROUTES", "/project/data");
          commit("UPDATE_SIDEBAR_ROUTES", [newRoutes, 8]);
          resolve(newRoutes);
        });
      });
    },
}

注意

先清除后添加路由

src/store/modules/permission.js 中,GeneProAppRoutes 里没有 commit SET_SIDEBAR_ROUTERS 来直接更新 sidebarRouters,而是先 REMOVE_SIDEBAR_ROUTESUPDATE_SIDEBAR_ROUTES

原因是:若不先清除路由,则随着切换项目的增多,sidebarRouters 中会累计越来越多的路由,会报错。

动态路由页面刷新404

参考网上把 404 路由注释掉,就可解决。
但又产生了一个新问题,若输入错误路由地址,就不会显示 404 页面。

参考链接

  1. vue 动态路由 addRoutes 刷新页面404(空白)
  2. vue 使用addRoutes动态添加路由 跳转404路由的问题

posted on 2023-05-30 16:25  shayloyuki  阅读(1423)  评论(0编辑  收藏  举报

导航