侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

vue实现后台管理权限系统及顶栏三级菜单显示功能

前端  /  管理员 发布于 5年前   1330

•效果演示地址

项目demo展示

重要功能总结

权限功能的实现

权限路由思路:

 根据用户登录的roles信息与路由中配置的roles信息进行比较过滤,生成可以访问的路由表,并通过router.addRoutes(store.getters.addRouters)动态添加可访问权限路由表,从而实现左侧和顶栏菜单的展示。

实现步骤:

1.在router/index.js中,给相应的菜单设置默认的roles信息;

如下:给"权限设置"菜单设置的权限为:meta:{roles: ['admin', 'editor']},及不同的角色都可以看到; 给其子菜单"页面权限",设置权限为:meta:{roles: ['admin']},及表示只有"admin"可以看到该菜单; 给其子菜单"按钮权限"设置权限为:meta:{roles: ['editor']},及表示只有"editor"可以看到该菜单。

2.通过router.beforeEach()和router.afterEach()进行路由过滤和权限拦截;

代码如下:

// permission judge functionfunction hasPermission(roles, permissionRoles) { if (roles.indexOf('admin') >= 0) return true // admin permission passed directly if (!permissionRoles) return true return roles.some(role => permissionRoles.indexOf(role) >= 0)}const whiteList = ['/login'] // 不重定向白名单router.beforeEach((to, from, next) => { NProgress.start() // 设置浏览器头部标题 const browserHeaderTitle = to.meta.title store.commit('SET_BROWSERHEADERTITLE', { browserHeaderTitle: browserHeaderTitle }) // 点击登录时,拿到了token并存入了vuex; if (getToken()) { /* has token*/ if (store.getters.isLock && to.path !== '/lock') { next({ path: '/lock' }) NProgress.done() } else if (to.path === '/login') { next({ path: '/' }) // 会匹配到path:'',后面的path:'*'还没有生成; NProgress.done()  } else { if (store.getters.roles.length === 0) { store.dispatch('GetInfo').then(res => { // 拉取用户信息  const roles = res.roles  store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表  router.addRoutes(store.getters.addRouters) // 动态添加可访问权限路由表  next({ ...to, replace: true }) // hack方法 确保addRoutes已完成  }) }).catch((err) => {  store.dispatch('FedLogOut').then(() => {  Message.error(err || 'Verification failed, please login again')  next({ path: '/' })  }) }) } else { // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ if (hasPermission(store.getters.roles, to.meta.roles)) {  next()// } else {  next({ path: '/401', replace: true, query: { noGoBack: true }}) } } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { // 点击退出时,会定位到这里 next('/login') NProgress.done() } }})router.afterEach(() => { NProgress.done() // 结束Progress setTimeout(() => { const browserHeaderTitle = store.getters.browserHeaderTitle setTitle(browserHeaderTitle) }, 0)})

用户点击登录之后的业务逻辑分析:

1、用户调取登录接口,获取到token,进行路由跳转到首页;

2、通过路由导航钩子router.beforeEach((to,from,next)=>{})函数确定下一步的跳转逻辑,如下:
2.1、用户已经登录成功并返回token值;

 2.1.1、lock 锁屏场景; 

 2.1.2、用户重新定位到登录页面; 

  2.1.3、根据用户是否有roles信息,进行不同的业务逻辑,如下:  

    (1)、初始情况下,用户roles信息为空;

        通过store.dispatch('GetInfo')调取接口,获取用户信息;
        获取到roles信息后,将roles,name,avatar保存到vuex;
        同时,通过store.dispatch('GenerateRoutes', { roles })去重新过滤和生成路由,并将重新生成之后的权限路由'routes'保存到vuex;
        最后,通过router.addRoutes()合并路由表;  
        如果在获取用户信息接口时,出现错误,则调取store.dispatch('FedLogOut')接口,返回到login页面;
        用户FedLogOut之后,需要情况vuex和localStorage中的token信息;         

   (2)、用户已经拥有roles信息;

        点击页面路由,通过roles权限判断 hasPermission();
        如果用户有该路由权限,直接跳转对应的页面;如果没有权限,则跳转至401提示页面;

2.2、用户没有获取到token值;

  2.2.1、如果设置了白名单用户,则直接跳转到相应的页面;反之,则跳转至登录页面; 

3、通过路由导航钩子函数router.afterEach(() => {}),做收尾工作,如下:
3.1、NProgress.done() // 结束Progress
3.2、获取到title并设置title;

详细代码,请参考src/permission.js

4、权限演示说明

测试账号:

(1). username: admin,password: 123456;admin拥有最高权限,可以查看所有的页面和按钮;

(2). username: editor,password: 123456;editor只有被赋予权限的页面和按钮才可以看到;

三级导航菜单顶部栏展示

如图所示,在完成一般后台系统所具有的二级导航菜单功能之后,我发现其实很多的后台管理系统都有三级导航菜单,但是如果都把三级菜单放到左侧菜单做阶梯状排列,就会显得比较紧凑,因此我觉得把所有的三级菜单放到顶部是一个不错的选择。

开发需求:点击左侧菜单,找到其对应的菜单(顶栏菜单)排放于顶部导航栏;

开发步骤:

1、 定义顶部导航组件topMenu.vue;

通过element-ui,NavMenu 导航菜单来进行顶部菜单的展示,注意顶栏和侧栏设置的区别;同时将其引用于头部组件headNav.vue中;

2、定义顶栏路由数据router/topRouter.js;

格式如下:

export const topRouterMap = [ { 'parentName':'infoShow', 'topmenulist':[  {  path: 'infoShow1',  name: 'infoShow1',  meta: {   title: '个人信息子菜单1',   icon: 'fa-asterisk',   routerType: 'topmenu'  },  component: () => import('@/page/fundList/moneyData')  } ] }, { 'parentName':'chinaTabsList', 'topmenulist':[  {  path:'chinaTabsList1',  name:'chinaTabsList1',  meta:{   title:'区域投资子菜单1',   icon:'fa-asterisk',   routerType:'topmenu'  },  component: () => import('@/page/fundList/moneyData')  } ] }]

定义topRouterMap为路由总数组;通过parentName来与左侧路由建立联系;通过topmenulist表示该顶栏路由的值;通过meta.routerType的值为"topmenu"或"leftmenu"来区分是顶栏路由,还是左侧路由;

3、 准备headNav.vue中渲染数据;

思路:点击左侧菜单,需要显示顶部对应的菜单。因为左侧菜单要和顶部菜单建立联系。我们知道导航菜单在用户登录时,会根据用户的role信息进行权限过滤;那么,在过滤权限路由数据之前,我们可以通过addTopRouter()将所有的三级菜单进行过滤添加,添加完成之后,继续进行角色过滤,可以保证将不具备权限的顶部菜单也过滤掉。

// 通过循环过滤,生成新的二级菜单function addTopRouter(){ asyncRouterMap.forEach( (item) => { if(item.children && item.children.length >= 1){ item.children.forEach((sitem) => { topRouterMap.forEach((citem) => {  if(sitem.name === citem.parentName){  let newChildren = item.children.concat(citem.topmenulist);  item.children = newChildren;  } }) }) } }) return asyncRouterMap;}

4、点击左侧菜单过滤路由并显示对应数据;

在组件topMenu.vue中,用户默认进来或者点击左侧菜单,触发setLeftInnerMenu()函数,如下:

 setLeftInnerMenu(){ if(this.$route.meta.routerType == 'leftmenu'){ // 点击的为 左侧的2级菜单 this.$store.dispatch(''ClickLeftInnerMenu,  {'name':this.$route.name} ); }else{ // 点击顶部的菜单 this.$store.dispatch('ClickTopMenu',  {'title':this.$route.meta.title} ); }}

通过当前路由this.$route.meta.routerType的值判断,用户是点击顶部菜单还是左侧菜单。如果点击顶部菜单,通过this.$store触发异步动作'ClickLeftInnerMenu'并传递参数'name',vuex中通过state.topRouters = filterTopRouters(state.routers,data)过滤当前路由信息;代码如下:

// 获取到当前路由对应顶部子菜单 function filterTopRouters(data){ let topRouters = topRouterMap.find((item)=>{ return item.parentName === data.name }) if(!mutils.isEmpty(topRouters)){ return topRouters.topmenulist; }}

topMenu.vue中,通过 computed:{ ...mapGetters(['topRouters'])}进行对应顶部路由数据的展示。用户每次点击左侧菜单时,顶部路由都进行了重新赋值并渲染,保证了数据的准确性。

5、顶部菜单完善;

当顶部菜单的数据量过大时,我们需要设置横向滚动条并设置滚动条的样式。
 如图:

mock数据详解

easy-mock使用

Easy Mock介绍:

•Easy Mock 是一个可视化,并且能快速生成 模拟数据 的持久化服务,
•Easy Mock 支持基于 Swagger 创建项目,以节省手动创建接口的时间;
•简单点说:Easy Mock就是一个在线创建mock的服务平台,帮你省去你 配置、安装、起服务、维护、多人协作Mock数据不互通等一系列繁琐的操作, 它能在不用1秒钟的时间内给你所要的一切。

详细使用方法,包含新建项目,基础语法,数据占位符,Swagger等介绍和使用,请参考详细文档

easy-mock,在本项目中的使用:

1.按照官方文档,创建个人项目vue-touzi-admin;

根据项目需要,创建的接口有:用户登录接口:"/user/login";获取用户信息接口:"/user/info";用户登出接口:"/user/logout";获取所有用户列表接口:"/user/getUserList";如图:

登录接口在easy-mock端编写的逻辑如下:

{ code: function({ _req }) { if (_req.body.username === "admin" || _req.body.username === "editor" && _req.body.password === "123456") { return 200 } else { return -1 } }, message: function({ _req }) { if (_req.body.username !== "admin" || _req.body.username !== "editor") { return "账号或密码有误!" } }, data: function({ _req }) { if (_req.body.username == "admin" && _req.body.password === "123456") { return { code: 0, roles: ['admin'], token: 'admin', introduction: '我是超级管理员', name: 'Super Admin' } } else if (_req.body.username === 'editor' && _req.body.password === "123456") { return { code: 0, roles: ['editor'], token: 'editor', introduction: '我是编辑', name: 'Normal Editor' } } else { return "账号或密码有误!" } }}

1.webpack中,开发环境和生产环境地址配置;生产环境,NODE_ENV: '"production"';如下:

module.exports = merge(prodEnv, { NODE_ENV: '"development"', API_BASE_URL: '"https://easy-mock.com/mock/5cd03667adb0973be6a3d8d1/api"',})

3.接口封装实例;如下:

import request from '@/utils/axios'export function login(username, password) { return request({ url: process.env.API_BASE_URL+'/user/login', method: 'post', data: { username, password } })}

mockjs使用

使用背景:

在使用easy-mock模拟数据的过程中,发现其对表格固定数据不能实现增删改等功能,因而选择了使用mockjs;

介绍及功能:

Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:

1.根据数据模板生成模拟数据,通过mockjs提供的方法,你可以轻松地创造大量随机的文本,数字,布尔值,日期,邮箱,链接,图片,颜色等.

2.模拟 Ajax 请求,生成并返回模拟数据,mockjs可以进行强大的ajax拦截.能判断请求类型,获取到url,请求参数等.然后可以返回mock的假数据,或者你自己编好的json文件.功能强大易上手.

3.基于 HTML 模板生成模拟数据

mockjs在本项目中使用:

1.安装mockjs

npm install mockjs --save-dev

2.创建mock文件夹结构并定义相关的功能模块;如图:

mockjs/index.js,负责定义相关的mock接口,如下:import Mock from 'mockjs'import tableAPI from './money'// 设置全局延时 没有延时的话有时候会检测不到数据变化 建议保留Mock.setup({ timeout: '300-600'})// 资金相关Mock.mock(/\/money\/get/, 'get', tableAPI.getMoneyList)Mock.mock(/\/money\/remove/, 'get', tableAPI.deleteMoney)Mock.mock(/\/money\/batchremove/, 'get', tableAPI.batchremoveMoney)Mock.mock(/\/money\/add/, 'get', tableAPI.createMoney)Mock.mock(/\/money\/edit/, 'get', tableAPI.updateMoney)

mockjs/money.js,则定义相关的函数,实现模拟数据的业务逻辑,比如资金流水数据的增删改查等;数据的生成规则请参照mockjs官网文档,上面有详细的语法说明;

3.在main.js中引入定义好的mockjs;如下:

import './mockjs'  //引用mock

4.mockjs,api接口封装;

src/api/money.js中,进行了统一的接口封装,在页面中调用对应函数,即可获取到相应的模拟数据。代码如下:

import request from '@/utils/axios'export function getMoneyIncomePay(params) { return request({ url: '/money/get', method: 'get', params: params })}export function addMoney(params) { return request({ url: '/money/add', method: 'get', params: params })}

5.组件中,接口调用,获取数据,渲染页面;

总结

以上所述是小编给大家介绍的vue实现后台管理权限系统及顶栏三级菜单显示功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

您可能感兴趣的文章:

  • vue中如何实现后台管理系统的权限控制的方法示例
  • 关于Vue的路由权限管理的示例代码
  • 详解VueJS应用中管理用户权限
  • 动态加载权限管理模块中的Vue组件
  • 基于vue实现网站前台的权限管理(前后端分离实践)
  • 详解利用 Vue.js 实现前后端分离的RBAC角色权限管理
  • Vue iview-admin框架二级菜单改为三级菜单的方法


  • 上一条:
    JavaScript箭头函数中的this详解
    下一条:
    js简单遍历获取对象中的属性值的方法示例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客