美文网首页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