美文网首页Vue.js
vue 路由与菜单统一

vue 路由与菜单统一

作者: zhudying | 来源:发表于2021-01-14 10:44 被阅读0次

    在做权限控制时候,往往采用由后端控制菜单和路由信息,但是如果后端维护两套数据会很麻烦,那我们可不可以用一套数据,来渲染菜单和路由。

    1. 首先是渲染菜单的组件

    略。

    2. 构建数据

    从后端拿来直接丢vuex里

    // 该数据可以直接渲染出菜单
    [
          {
            name: "系统设置",
            path: "/system",
            children: [
              {
                name: "用户管理",
                path: "/user",    // 所在文件名,也是路由
                file: '/system/user',  // 所在文件夹名称 
                meta: {
                  title: "用户管理"   
                }
              },
              {
                name: "权限管理",
                path: "/permission",
                file: '/system/permission',
                meta: {
                  title: "权限管理"
                }
              }
            ]
          }
    ]
    
    3. 路由信息
    1. 固定路由部分
      在 page 页面
    export default [
      {
        path: '/',
        redirect: '/login'
      },
      {
        path: '/login',
        name: 'login',
        component: () => import(/* webpackChunkName: "login" */"../views/login/login.vue")
      },
      {
        path: '*',
        name: '404',
        component: () => import('../views/error/404.vue')
      },
      {
        path: '/500',
        name: '500',
        component: () => import('../views/error/500.vue')
      }
    ]
    
    1. 动态路由
    export default {
      install(vue, router) {
        this.$router = router
        this.$router.$dynamicRouter = {
          routerList: [],
          self: this,
          formatRoutes: function (menu = [], first) {
            const aRouter = []
            if (menu.length <= 0) return
            for (let i = 0; menu.length > i; i++) {
              const iMenu = menu[i]
              if (this.routerList.includes(iMenu.path)) return;
    
              const path = (() => {
                if (first) {
                  return iMenu.path
                } else {
                  return iMenu.path
                }
              })(),
                component = iMenu.path,
                file = iMenu.file,
                name = iMenu.name,
                icon = iMenu.icon,
                children = iMenu.children,
                meta = iMenu.meta || {};
              const isChild = children;
              const oRouter = {
                path: path,
                icon: icon,
                meta: meta,
                component: () => {
                  if (first) {
                    return import("../layout/index.vue")
                  } else if (isChild && !first) {
                    return import("../layout/index.vue")
                  } else {
                    return import(`../views${file}${component}.vue`)
                  }
                },
                children: (!isChild) ? (() => {
                  if (first) {
                    return [
                      {
                        path: path,
                        name: name,
                        icon: icon,
                        meta: meta,
                        component: () => import(`../views${file}${component}.vue`),
                      }
                    ]
                  }
                  return [];
                })() : (() => {
                  return this.formatRoutes(children, false)
                })()
              }
              aRouter.push(oRouter)
            }
            if (first) {
              if (!this.routerList.includes(aRouter[0].path)) {
                this.self.$router.addRoutes(aRouter)
                this.routerList.push(aRouter[0].path)
              }
            } else {
              return aRouter
            }
          }
        }
      }
    }
    

    重构出来的路由是这样的

    [
        {
            path: "/system",
            component:()=>import("../layout/index.vue"),
            meta: {},
            icon: "",
            children: [
                {
                    path: "/user",
                    name:"用户管理",
                    component:()=>import("../views/system/user/user.vue"),
                    meta: {
                        title: "用户管理"   
                   },
                    icon: "",
                },
                {
                    path: "/permission",
                    name:"权限管理",
                    component:()=>import("../views/system/permission/permission.vue"),
                    meta: {
                        title: "权限管理"   
                   },
                    icon: "",
                }
            ]
        }
    
    ]
    
    1. addRoutes
    import Vue from "vue";
    import VueRouter from "vue-router";
    import page from './page';
    import dynamicRouter from './reset-router';
    import Store from '../store/index';
    Vue.use(VueRouter);
    /**
     * 重写路由的push方法
     */
    const routerPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function push(location) {
      return routerPush.call(this, location).catch(error => error);
    };
    
    const router = new VueRouter({
      mode: "history",
      routes: []
    });
    dynamicRouter.install(Vue, router, Store);
    // Store.state.user.menuList  数据从后端拿过来后放在了vuex state 的menuList中
    router.$dynamicRouter.formatRoutes(Store.state.user.menuList, true);
    
    router.addRoutes([...page]);
    export default router;
    
    

    相关文章

      网友评论

        本文标题:vue 路由与菜单统一

        本文链接:https://www.haomeiwen.com/subject/gfkiwktx.html