el-admin项目和el-element-admin项目路由比较

由于公司的项目使用的是el-admin项目的开源框架,最近在学习el-template-admin项目时,发现两者的路由权限有很大的不同,总结一下,方便日后使用:

1、el-admin开源项目使用的是动态路由,权限和动态路由都是在后端配置的,前端没有使用控制权限,缺点就是,前端人员要想画页面,就要通知后端人员配置路由和权限,没有做到完全的进行前后端分离。

2、el-element-admin是前端配置的路由,可以在前端配置路由权限,给路由分配权限。

el-admin开源项目的路由设计:

1、首先在router/router.js中进行路由的配置,注意这里手动配置不需要权限的路由,那些需要权限的路由是通过请求后端接口实现的。附上源码:

1、api/system/menu.js   前端请求后端的接口

import request from '@/utils/request'

export function buildMenus() {
  return request({
    url: 'yj/iscUserLocext/menus',
    method: 'get'
  })
}


2、router/index.js

.......

import { buildMenus } from '@/api/system/menu'   // 请求路由的api
import { filterAsyncRouter } from '@/store/modules/permission'  // 遍历后台传来的路由字符串,转换为组件对象

.......

const whiteList = ['/login']// no redirect whitelist

router.beforeEach((to, from, next) => {
  if (to.meta.title) {
    document.title = to.meta.title + ' - ' + Config.title
  }
  NProgress.start()
  if (getToken()) {
    // 已登录且要跳转的页面是登录页
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
        store.dispatch('GetInfo').then(res => { // 拉取user_info
         
         // 动态路由,拉取菜单
          loadMenus(next, to)

        }).catch((err) => {
          console.log(err)
          store.dispatch('LogOut').then(() => {
            location.reload() // 为了重新实例化vue-router对象 避免bug
          })
        })
      // 登录时未拉取 菜单,在此处拉取
      } else if (store.getters.loadMenus) {
        // 修改成false,防止死循环
        store.dispatch('updateLoadMenus').then(res => {})
        loadMenus(next, to)
      } else {
        next()
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
})

// 动态获取路由
export const loadMenus = (next, to) => {
  buildMenus().then(res => {
    const asyncRouter = filterAsyncRouter(res)
    asyncRouter.push({ path: '*', redirect: '/404', hidden: true })
    store.dispatch('GenerateRoutes', asyncRouter).then(() => { // 存储路由
      router.addRoutes(asyncRouter) // 动态添加可访问路由表
      next({ ...to, replace: true })
    })
  })
}

router.afterEach(() => {
  NProgress.done() // finish progress bar(完成进度条)
})

3、store/module/permission.js

import { constantRouterMap } from '@/router/routers'
import Layout from '@/layout/index'

const permission = {
  state: {

    routers: constantRouterMap,  // 默认是静态路由,这部分路由是公共的,从数据库中查询的路由会添加到其后面

    addRouters: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    }
  },
  actions: {
    GenerateRoutes({ commit }, asyncRouter) {
      commit('SET_ROUTERS', asyncRouter)
    }
  }
}

export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由字符串,转换为组件对象
  return routers.filter(router => {
    if (router.component) {
      if (router.component === 'Layout') { // Layout组件特殊处理
        router.component = Layout
      } else {
        const component = router.component
        router.component = loadView(component)
      }
    }
    if (router.children && router.children.length) {
      router.children = filterAsyncRouter(router.children)
    }
    return true
  })
}

export const loadView = (view) => {
  return (resolve) => require([`@/views/${view}`], resolve)
}

export default permission

4、store/getters.js

const getters = {
  .......

  loadMenus: state => state.user.loadMenus,
  permission_routers: state => state.permission.routers,
  addRouters: state => state.permission.addRouters,

  .......
}
export default getters

5、Sidebar/index.vue

<template>
  <div :class="{'has-logo':showLogo}">
   
    <el-scrollbar wrap-class="scrollbar-wrapper">
      <el-menu
       .....
      >
        <sidebar-item v-for="route in permission_routers" :key="route.path" :item="route" :base-path="route.path" />
      </el-menu>

    </el-scrollbar>
    
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  .....

  computed: {
    ...mapGetters([
      'permission_routers',
      'sidebar'
    ]),

   ......
  }
}
</script>

el-admin项目的动态路由大概就是这么实现的。

 

el-element-admin开源项目的路由设计:

1、el-element-admin项目的路由和权限是在前端配置的,最大的区别是permission.js不同:

import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission(使用元。角色确定当前用户是否具有权限)
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion(通过递归过滤异步路由表)
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],    // 默认为空
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

2、使用mock模拟数据: mock/index.js, 分配权限

const Mock = require('mockjs')
const { deepClone } = require('../utils')
const { asyncRoutes, constantRoutes } = require('./routes.js')

const routes = deepClone([...constantRoutes, ...asyncRoutes])

const roles = [
  {
    key: 'admin',
    name: 'admin',
    description: '超级管理员。可以查看所有页面',
    routes: routes
  },
  {
    key: 'editor',
    name: 'editor',
    description: '正常的编辑器。可以看到所有页面除了权限页',
    routes: routes.filter(i => i.path !== '/permission')// just a mock
  },
  {
    key: 'visitor',
    name: 'visitor',
    description: '只是一个游客,只能看到主页和文档页',
    routes: [{
      path: '',
      redirect: 'dashboard',
      children: [
        {
          path: 'dashboard',
          name: 'Dashboard',
          meta: { title: 'dashboard', icon: 'dashboard' }
        }
      ]
    }]
  }
]

module.exports = [
  // mock get all routes form server
  {
    url: '/vue-element-admin/routes',
    type: 'get',
    response: _ => {
      return {
        code: 20000,
        data: routes
      }
    }
  },

  // mock get all roles form server
  {
    url: '/vue-element-admin/roles',
    type: 'get',
    response: _ => {
      return {
        code: 20000,
        data: roles
      }
    }
  },

  // add role
  {
    url: '/vue-element-admin/role',
    type: 'post',
    response: {
      code: 20000,
      data: {
        key: Mock.mock('@integer(300, 5000)')
      }
    }
  },

  // update role
  {
    url: '/vue-element-admin/role/[A-Za-z0-9]',
    type: 'put',
    response: {
      code: 20000,
      data: {
        status: 'success'
      }
    }
  },

  // delete role
  {
    url: '/vue-element-admin/role/[A-Za-z0-9]',
    type: 'delete',
    response: {
      code: 20000,
      data: {
        status: 'success'
      }
    }
  }
]

3、mock/role/routes.js,  在该文件中,所有的路由都已经配置好了。

// Just a mock data

const constantRoutes = [
  {
    path: '/redirect',
    component: 'layout/Layout',
    hidden: true,
    children: [
      {
        path: '/redirect/:path*',
        component: 'views/redirect/index'
      }
    ]
  },
  {
    path: '/login',
    component: 'views/login/index',
    hidden: true
  },
  {
    path: '/auth-redirect',
    component: 'views/login/auth-redirect',
    hidden: true
  },
  {
    path: '/404',
    component: 'views/error-page/404',
    hidden: true
  },
  {
    path: '/401',
    component: 'views/error-page/401',
    hidden: true
  },
  {
    path: '',
    component: 'layout/Layout',
    redirect: 'dashboard',
    children: [
      {
        path: 'dashboard',
        component: 'views/dashboard/index',
        name: 'Dashboard',
        meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
      }
    ]
  },
 
]

const asyncRoutes = [
  {
    path: '/permission',
    component: 'layout/Layout',
    redirect: '/permission/index',
    alwaysShow: true,
    meta: {
      title: 'Permission',
      icon: 'lock',
      roles: ['admin', 'editor']
    },
    children: [
      {
        path: 'page',
        component: 'views/permission/page',
        name: 'PagePermission',
        meta: {
          title: 'Page Permission',
          roles: ['admin']
        }
      },
      {
        path: 'directive',
        component: 'views/permission/directive',
        name: 'DirectivePermission',
        meta: {
          title: 'Directive Permission'
        }
      },
      {
        path: 'role',
        component: 'views/permission/role',
        name: 'RolePermission',
        meta: {
          title: 'Role Permission',
          roles: ['admin']
        }
      }
    ]
  },

 
  },
 
 

  .......
  

  {
    path: 'external-link',
    component: 'layout/Layout',
    children: [
      {
        path: 'https://github.com/PanJiaChen/vue-element-admin',
        meta: { title: 'External Link', icon: 'link' }
      }
    ]
  },

  { path: '*', redirect: '/404', hidden: true }
]

module.exports = {
  constantRoutes,
  asyncRoutes
}

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
el-admin后台管理系统是一个基于 Spring Boot 2.1.0 、 Spring boot Jpa、 Spring Security、redis、Vue的前后端分离的权限管理系统,项目采用分模块开发方式, 权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制),前端菜单支持动态路由el-admin后台管理系统特点: 1、使用最新技术栈,社区资源丰富。 2、高效率开发,代码生成器可一键生成前后端代码 3、支持数据字典,可方便地对一些状态进行管理 4、支持接口限流,避免恶意请求导致服务层压力过大 5、支持接口级别的功能权限与数据权限,可自定义操作 6、自定义权限注解与匿名接口注解,可快速对接口拦截与放行 7、对一些常用地前端组件封装:表格数据请求、数据字典等 8、前后端统一异常拦截处理,统一输出异常,避免繁琐的判断 9、支持在线用户管理与服务器性能监控,支持限制单用户登录 10、支持运维管理,可方便地对远程服务器的应用进行部署与管理 el-admin后台管理系统功能: 用户管理:提供用户的相关配置,新增用户后,默认密码为123456 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单 部门管理:可配置系统组织架构,树形表格展示 岗位管理:配置各个部门的职位 字典管理:可维护常用一些固定的数据,如:状态,性别等 系统日志:记录用户操作日志与异常日志,方便开发人员定位拍错 SQL监控:采用druid 监控数据库访问性能,默认用户名admin,密码123456 定时任务:整合Quartz做定时任务,加入任务日志,任务运行情况一目了然 代码生成:高灵活度生成前后端代码,减少大量重复的工作任务 邮件工具:配合富文本,发送html格式的邮件 免费图床:使用sm.ms图床,用作公共图片上传使用,该图床不怎么稳定,不太建议使用 七牛云存储:可同步七牛云存储的数据到系统,无需登录七牛云直接操作云数据 支付宝支付:整合了支付宝支付并且提供了测试账号,可自行测试 服务监控:监控服务器的负载情况 运维管理:一键部署你的应用 用户账号密码 管理员:admin 测试用户:test 密码:123456 开发环境 JDK:8 IDE:IntelliJ IDEA (后端) IDE:JetBrains WebStorm (前端) 依赖管理:Maven 数据库:MySQL 5.5.59     el-admin后台管理系统 v2.6 更新日志: 本次升级解决了2.5版本中存在影响日常使用的问题,主要为菜单分配与缓存问题 优化 1、匿名接口SecurityConfig配置细腻化,支持不同类型的接口放行 2、验证码类型、长度、字体等参数可在配置文件中自定义 3、前端代码生成日期选择改为 date-range-picker 组件 4、Query 注解加入 INNER 查询,代码生成器细节优化 5、其他细节优化 修复 1、修复管理员修改用户的 username 后,用旧的用户名称还能登陆的问题 2、修复EncryptUtils 优化在linux中,存在解密乱码的情况 3、修复禁用用户后用户还可以操作的Bug 4、修复算数型验证码生成浮点型结果,导致前端输入整形数据匹配错误 5、修复菜单分配后菜单数据丢失的问题,修复缓存引起的一些问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值