vue实现权限控制路由(vue-router 动态添加路由)


Posted in Javascript onNovember 04, 2019

用户登录后返回权限菜单,前端根据权限菜单动态添加路由,然后再动态生成菜单栏。

思路如下:

一、定义初始化默认路由。

vue实现权限控制路由(vue-router 动态添加路由)

二、动态配置路由,这里是把所有组件中相应的路由配置成一个个的对象,根据后台返回的菜单tree一个个去匹配。

vue实现权限控制路由(vue-router 动态添加路由)

三、通过匹配,把匹配好的路由数据addRoutes到路由中。

vue实现权限控制路由(vue-router 动态添加路由)

四、为了防止刷新页面后路由数据被清空,这里用判断是否登录的方式,再次加载动态路由。

vue实现权限控制路由(vue-router 动态添加路由)

具体代码如下:

router.js

import Vue from 'vue'
import {router} from './index'
import login from '@/views/login/login'
import layout from '@/views/layout/layout'
import home from '@/views/home/home.vue'
import depDsStorageList from '@/views/home/homePage1/depDsStorageList.vue'
 
 
// 数据管理
import dataSourceAdmin from '@/views/dataManage/dataSourceAdmin/dataSourceAdmin'
import dataPoolAdmin from '@/views/dataManage/dataPoolAdmin/dataPoolAdmin'
import buildSqlTable from '@/views/dataManage/buildSqlTable/buildSqlTable'
import complianceDetectionFunction from '@/views/dataManage/complianceDetectionFunction/complianceDetectionFunction'
import tablePreview from '@/views/dataManage/dataSourceAdmin/tablePreview/tablePreview.vue'
import dataAssetsManage from '@/views/dataManage/dataAssetsManage/dataAssetsManage.vue'
//标准管理
import codeItemManage from '@/views/standardManage/codeItemManage/codeItemManage'
import metadataManage from '@/views/standardManage/metadataManage/metadataManage'
import standardFileManage from '@/views/standardManage/standardFileManage/standardFileManage'
import determinerManage from '@/views/standardManage/determinerManage/determinerManage'
//数据服务
import dataServiceAdmin from '@/views/dataService/dataServiceAdmin/dataServiceAdmin.vue'
import customizedServiceAdmin from '@/views/dataService/customizedServiceAdmin/customizedServiceAdmin.vue'
 
//系统管理
import labelManage from '@/views/systemManage/labelManage/labelManage.vue'
import roleMenu from '@/views/systemManage/role-menu/role-menu.vue'
import userAdmin from '@/views/systemManage/user-admin/user-admin.vue'
import roleAdmin from '@/views/systemManage/role-admin/role-admin.vue'
 
//权限
import haveNoAuthority from '@/views/systemManage/NoAuthority/haveNoAuthority'
import haveNotFound from '@/views/systemManage/NoAuthority/haveNotFound'
 
//初始化默认路由
export let initMenu = [
 {path: '', redirect: '/login'},
 {
 path: '/login',
 name: 'login',
 component: login
 },
 {
 path: '/haveNoAuthority',
 name: 'haveNoAuthority',
 component: haveNoAuthority
 },
 {
 path: '/haveNotFound',
 name: 'haveNotFound',
 component: haveNotFound
 },
 {
 path: '',
 redirect: '/depDsStorageList',
 component: layout,
 children: [
  {
  path: 'depDsStorageList',
  name: '首页内容列表',
  component: depDsStorageList,
  },
 ],
 },
 {
 path: '',
 redirect: 'addDataService',
 component: layout,
 children: [
  {
  path: 'addDataService',
  name: '新增数据服务',
  component: () => import('@/views/dataService/dataServiceAdmin/addDataService.vue'),
  },
 ],
 },
 {
 path: '',
 redirect: '/dataPoolAdmin',
 component: layout,
 children: [
  {
  path: 'dataPoolAdmin',
  name: '数据池管理',
  component: dataPoolAdmin
  },
 ],
 },
 {
 path: '',
 redirect: '/tablePreview',
 component: layout,
 children: [
  {
  path: 'tablePreview',
  name: '表关系预览',
  component: tablePreview
  },
 ],
 },
]
 
//动态配置路由
export let menu = {
 "首页": {
 path: '',
 redirect: '/home',
 component: layout,
 children: [
  {
  path: 'home',
  name: '首页',
  component: home,
  }
 ],
 },
 "标准数据服务": {
 path: '',
 redirect: '/dataServiceAdmin',
 component: layout,
 children: [
  {
  path: 'dataServiceAdmin',
  name: '标准数据服务',
  component: dataServiceAdmin,
  }
 ],
 },
 "定制数据服务": {
 path: '',
 redirect: '/customizedServiceAdmin',
 component: layout,
 children: [
  {
  path: 'customizedServiceAdmin',
  name: '定制数据服务',
  component: customizedServiceAdmin,
  }
 ],
 },
 "数据源管理": {
 path: '',
 redirect: '/dataSourceAdmin',
 component: layout,
 children: [
  {
  path: 'dataSourceAdmin',
  name: '数据源管理',
  component: dataSourceAdmin,
  }
 ],
 },
 "数据资产管理": {
 path: '',
 redirect: '/dataAssetsManage',
 component: layout,
 children: [
  {
  path: 'dataAssetsManage',
  name: '数据资产管理',
  component: dataAssetsManage,
  }
 ],
 },
 "标签管理": {
 path: '',
 redirect: '/labelManage',
 component: layout,
 children: [
  {
  path: 'labelManage',
  name: '标签管理',
  component: labelManage,
  },
 ],
 },
 "标准规范管理": {
 path: '',
 redirect: '/standardFileManage',
 component: layout,
 children: [
  {
  path: 'standardFileManage',
  name: '标准规范管理',
  component: standardFileManage
  },
 ],
 },
 "数据元管理": {
 path: '',
 redirect: '/metadataManage',
 component: layout,
 children: [
  {
  path: 'metadataManage',
  name: '数据元管理',
  component: metadataManage
  },
 ],
 },
 "限定词管理": {
 path: '',
 redirect: '/determinerManage',
 component: layout,
 children: [
  {
  path: 'determinerManage',
  name: '限定词管理',
  component: determinerManage
  },
 ],
 },
 "代码项管理": {
 path: '',
 redirect: '/codeItemManage',
 component: layout,
 children: [
  {
  path: 'codeItemManage',
  name: '代码项管理',
  component: codeItemManage
  },
 ],
 },
 "依标建库": {
 path: '',
 redirect: '/buildSqlTable',
 component: layout,
 children: [
  {
  path: 'buildSqlTable',
  name: '依标建库',
  component: buildSqlTable
  },
 ],
 },
 "合规检测": {
 path: '',
 redirect: '/complianceDetectionFunction',
 component: layout,
 children: [
  {
  path: 'complianceDetectionFunction',
  name: '合规检测',
  component: complianceDetectionFunction
  },
 ],
 },
 "用户管理": {
 path: '',
 redirect: '/userAdmin',
 component: layout,
 children: [
  {
  path: 'userAdmin',
  name: '用户管理',
  component: userAdmin
  },
 ],
 },
 "权限管理": {
 path: '',
 redirect: '/roleAdmin',
 component: layout,
 children: [
  {
  path: 'roleAdmin',
  name: '权限管理',
  component: roleAdmin
  },
 ],
 },
 "角色资源管理": {
 path: '',
 redirect: '/roleMenu',
 component: layout,
 children: [
  {
  path: 'roleMenu',
  name: '角色资源管理',
  component: roleMenu
  }
 ],
 }
}
 
export let menuList = []
export const setMenuTree = function (menuTree) {
 let temp = new Vue({router})
 hanleFor(menuTree)
 temp.$router.addRoutes(menuList)
 temp.$router.addRoutes([{path: '*', redirect: '/' + menuList[0].redirect}])
}
 
const hanleFor = function (list){
 for (var i=0; i<list.length; i++) {
 if (list[i].children) {
  hanleFor(list[i].children)
 }else{
  menuList.push(menu[list[i].name])
 }
 }
}
export const routers = {
 router: initMenu
}

index.js

import Vue from 'vue'
import iView from 'iview'
import lodash from 'lodash'
import VueLodash from 'vue-lodash'
import Router from 'vue-router'
 
import { routers, menuList, setMenuTree } from './routers';
import 'iview/dist/styles/iview.css'
 
 
Vue.use(Router);
 
Vue.use(iView);
 
Vue.use(VueLodash, lodash);
 
export const router = new Router({
 routes: routers.router
})
 
export let getMenuFuc = function (list) {
 setMenuTree(list)
}
 
if (sessionStorage.getItem("role")) {
 getMenuFuc(JSON.parse(sessionStorage.getItem("menuTree")))
}
 
router.beforeEach((to, from, next) => {
 if (!sessionStorage.getItem("role") && to.name !== 'login') {
 next('/login')
 } else {
 next()
 }
})

login.vue

<template>
 <div class="jq22-container loginBody" style="padding-top:100px; width: 100%; height: 100%;">
 <div class="login-wrap" @keydown.enter="handleSubmit">
  <div class="login-html">
  <p class="title">江苏消防数据资源管理服务平台</p>
  <div class="hr"></div>
  <div class="login-form">
   <div class="sign-in-htm">
   <Form ref="loginForm" :model="form" :rules="rules">
   <div class="group group1">
    <FormItem prop="account">
    <Icon :size="20" type="person" class="icon-user"></Icon>
    <input v-model="form.account" type="text" class="input" placeholder="用户名">
    </FormItem>
   </div>
   <div class="group">
    <FormItem prop="password" v-show="hidePass">
    <Icon :size="16" type="locked" class="icon-pass"></Icon>
    <div @click="showPwd"><Icon :size="22" type="eye-disabled" class="eyeDisabled"></Icon></div>
    <input v-model="form.password" type="password" class="input" data-type="password" placeholder="密码">
    </FormItem>
    <FormItem prop="password" v-show="showPass">
    <Icon :size="16" type="locked" class="icon-pass"></Icon>
    <div @click="hidePwd"><Icon :size="22" type="eye" class="eyeDisabled"></Icon></div>
    <input v-model="form.password" type="text" class="input" data-type="text" placeholder="密码">
    </FormItem>
   </div>
   <div class="group">
    <!--<FormItem prop="code">-->
    <FormItem prop="code">
    <Icon :size="18" type="android-checkmark-circle" class="icon-pass"></Icon>
    <input v-model="form.code" type="text" class="input" data-type="text" placeholder="验证码" maxlength="4">
    <img id="imgObj" alt="验证码" :src="cfg.api.obtain" @click="changeImg"/>
    </FormItem>
   </div>
   <!--<div class="group">
    <input id="check" type="checkbox" class="check" checked>
    <label for="check"><span class="icon"></span> 记住密码</label>
    <a href="#forgot" rel="external nofollow" style="float: right">忘记密码?</a>
   </div>-->
   <Alert type="error" v-show="error">
    <span style="color: red">{{errorMessage}}</span>
   </Alert>
   <div class="group">
    <input type="button" class="button" value="登录" @click="handleSubmit">
   </div>
   </Form>
   </div>
  </div>
  <div span="8" v-show="spinShow">
   <Spin fix>
   <Icon type="load-c" size=50 class="demo-spin-icon-load"></Icon>
   <div>登录中,请稍后...</div>
   </Spin>
  </div>
  </div>
 </div>
 </div>
</template>
<style>
 @import "./login.css";
</style>
<script src="./loginJs.js"></script>

login.css

body{
 margin: 0 auto;
 padding: 0;
 width: 100%;
 color:#6a6f8c;
 background: url("./img/login_1.png");
 background-size: cover;
}
body,html,.loginBody{
 height: 100%;
}
input, button {
 outline: none;
 border: none;
}
.title{
 text-align: center;
 color: #f3f3f3;
 font-size: 24px;
 margin-bottom: 40px;
 font-weight: bold;
}
.login-wrap{
 width:100%;
 margin: auto;
 max-width:400px;
 min-height:500px;
 position:relative;
 background:url(./img/login_1.png);
 box-shadow:0 12px 15px 0 rgba(0,0,0,.24),0 17px 50px 0 rgba(0,0,0,.19);
 margin-top: 4%;
}
.login-html{
 width:100%;
 height:100%;
 position:absolute;
 background:rgba(40,57,101,.9);
 padding: 50px 20px 30px 20px;
}
.ivu-form-item-content{
 height: 50px;
}
.login-form .group1{
 position: relative;
}
.icon-user{
 position: absolute ;
 left: 10px;
 top: 12px;
 z-index: 5;
 color: #666;
 
}
.login-form .group2{
 position: relative;
 padding-bottom: 10px;
}
.icon-pass{
 position: absolute ;
 left: 10px;
 top: 13px;
 z-index: 5;
 color: #666;
}
#imgObj{
 position: absolute ;
 width:40%;
 height: 30px;
 z-index: 5;
 left: 58%;
 top: 7px;
 border-radius:15px;
 opacity: 0.7;
}
.eyeDisabled{
 position: absolute ;
 left: 91%;
 top: 10px;
 z-index: 5;
 color: #666;
}
.eyeDisabled:hover{
 cursor: pointer;
}
.login-form .group .input{
 width:100%;
 color:#fff;
 display:block;
 text-indent: 23px;
 font-size: 15px;
 border:none;
 padding:5px 10px;
 border-radius:25px;
 background:rgba(255,255,255,.1);
}
.login-form .group .button{
 width:100%;
 color:#fff;
 display:block;
 border:none;
 padding:15px 20px;
 border-radius:25px;
 background:rgba(255,255,255,.1);
 margin-top: 20px;
}
.login-form .group input[data-type="password"]{
 text-security:circle;
 -webkit-text-security:circle;
}
 
.login-form .group .button{
 background:#1161ee;
}
.hr{
 height:2px;
 margin:20px 0 30px 0;
 background:rgba(255,255,255,.2);
}
.foot-lnk{
 text-align:center;
}
#imgObj:hover{
 cursor: pointer;
}
 .demo-spin-icon-load{
 animation: ani-demo-spin 1s linear infinite;
}
@keyframes ani-demo-spin {
 from { transform: rotate(0deg);}
 50% { transform: rotate(180deg);}
 to { transform: rotate(360deg);}
}

loginJs.js

import {getMenuFuc} from '../../router/index'
export default {
 data () {
 return {
  form: {
  account: 'admin',
  password: '123456',
  code: ''
  },
  rules: {
  account: [
   { required: true, message: '账号不能为空', trigger: 'blur' }
  ],
  password: [
   { required: true, message: '密码不能为空', trigger: 'blur' }
  ],
  code: [
   { required: true, message: '验证码不能为空', trigger: 'blur' }
  ]
  },
  showPass: false,
  hidePass: true,
  error: false,
  errorMessage: '',
  token: '',
  imgUrl: '',
  validate: '',
  spinShow:false
 };
 },
 created (){
 let _this = this
 _this.token = this.getCookie('token')
 _this.changeImg()
 $(".demo-spin-col").height($("body").height())
 },
 methods: {
 showPwd () {
  this.hidePass = false
  this.showPass = true
 },
 hidePwd () {
  this.hidePass = true
  this.showPass = false
 },
 handleSubmit () {
  let _this = this
  _this.$refs.loginForm.validate((valid) => {
  if (valid) {
   _this.spinShow = true
   _this.$ajax.post(_this.cfg.api.login, _this.form).then(function(res){
   if(res.data.result){
    _this.setCookie('token',res.data.token, 365)
    let role = res.data.data.role
    var roleString = ''
    for (var i=0; i<role.length; i++) {
    if (i == role.length-1) {
     roleString += role[i].roleName
    }else{
     roleString += role[i].roleName + ','
    }
    }
    sessionStorage.setItem("account",_this.form.account)
    sessionStorage.setItem("role",roleString)
 
    let menuTree = res.data.data.menuTree
    sessionStorage.setItem("menuTree",JSON.stringify(menuTree))//用于layout页面加载菜单
 
    let buttonList = res.data.data.buttonList //存储按钮的权限控制
    sessionStorage.setItem("buttonList",JSON.stringify(buttonList))
    getMenuFuc(menuTree)
    _this.$router.push('home');
 
    _this.error = false
   }else{
    _this.error = true
    _this.errorMessage = res.data.message
    _this.form.code = ''
    _this.changeImg()
   }
   _this.spinShow = false
   }).catch((error)=>{ _this.spinShow = false});
  }
  });
 },
 changeImg() {
  var imgSrc = $("#imgObj");
  var src = imgSrc.attr("src");
  imgSrc.attr("src", this.changeUrl(src));
 },
 changeUrl(url) {
  var timestamp = (new Date()).valueOf();
  var index = url.indexOf("?",url);
  if (index > 0) {
  url = url.substring(0, index);
  }
  if ((url.indexOf("&") >= 0)) {
  url = url + "×tamp=" + timestamp;
  } else {
  url = url + "?timestamp=" + timestamp;
  }
  return url;
 }
 }
};

以上这篇vue实现权限控制路由(vue-router 动态添加路由)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
Feb 04 Javascript
JQuery jsonp 使用示例代码
Aug 12 Javascript
jquery简单瀑布流实现原理及ie8下测试代码
Jan 23 Javascript
一个很有趣3D球状标签云兼容IE8
Aug 22 Javascript
jQuery layui常用方法介绍
Jul 25 Javascript
Angular2 (RC5) 路由与导航详解
Sep 21 Javascript
js实现手机发送验证码功能
Mar 13 Javascript
Angular中的$watch、$watchGroup、$watchCollection
Jun 25 Javascript
Validform验证时可以为空否则按照指定格式验证
Oct 20 Javascript
vue-router+nginx 非根路径配置方法
Jun 30 Javascript
Vue实现手机扫描二维码预览页面效果
May 28 Javascript
AngularJS实现多级下拉框
Mar 25 Javascript
Vue路由对象属性 .meta $route.matched详解
Nov 04 #Javascript
element-ui table组件如何使用render属性的实现
Nov 04 #Javascript
Vue 解决多级动态面包屑导航的问题
Nov 04 #Javascript
vue+elementUI动态生成面包屑导航教程
Nov 04 #Javascript
VUE+elementui面包屑实现动态路由详解
Nov 04 #Javascript
Vuex,iView UI面包屑导航使用扩展详解
Nov 04 #Javascript
vue双向绑定数据限制长度的方法
Nov 04 #Javascript
You might like
mysql 字段类型说明
2007/04/27 PHP
在WINDOWS中设置计划任务执行PHP文件的方法
2011/12/19 PHP
深入PHP与浏览器缓存的分析
2013/06/03 PHP
php 数组处理函数extract详解及实例代码
2016/11/23 PHP
PHP JWT初识及其简单示例
2018/10/10 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
预加载css或javascript的js代码
2010/04/23 Javascript
jQuery实现动画效果的实例代码
2013/05/07 Javascript
动态标签 悬停效果 延迟加载示例代码
2013/11/21 Javascript
javascript字符串函数汇总
2015/12/06 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
完美实现js选项卡切换效果(二)
2017/03/08 Javascript
Vue2.x中的父组件传递数据至子组件的方法
2017/05/01 Javascript
vue-cli+webpack在生成的项目中使用bootstrap实例代码
2017/05/26 Javascript
详解组件库的webpack构建速度优化
2018/06/18 Javascript
VUE+Element环境搭建与安装的方法步骤
2019/01/24 Javascript
Vue.js数字输入框组件使用方法详解
2019/10/19 Javascript
[04:03]DOTA2肉山黑名单梦之声 风暴之灵中文配音鉴赏
2013/07/03 DOTA
[40:13]Ti4 冒泡赛第二天 iG vs NEWBEE 2
2014/07/15 DOTA
python使用range函数计算一组数和的方法
2015/05/07 Python
python获取外网ip地址的方法总结
2015/07/02 Python
Python爬取当当、京东、亚马逊图书信息代码实例
2017/12/09 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
Python+Selenium实现自动化的环境搭建的步骤(图文)
2020/09/01 Python
html5使用canvas画空心圆与实心圆
2014/12/15 HTML / CSS
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
英国创新设计文具、卡片和礼品包装网站:Paperchase
2018/07/14 全球购物
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
简短的公司员工自我评价分享
2013/11/13 职场文书
文明好少年事迹材料
2014/08/19 职场文书
二胎满月酒致辞
2015/07/29 职场文书
2019年教师入党申请书
2019/06/27 职场文书
Python实现8种常用抽样方法
2021/06/27 Python