一、菜单权限的实现:

在登录请求中会得到权限数据,当然这个需要后端返回数据的支持,前端根据权限数据展示对应的菜单,点击菜单才能查看相应的界面。

登录之后获取到的数据:

[{path: "/main/data",alias: "/data",name: "data",meta: {title: "统计",icon: "el-icon-house",requireAuth: true},children: [{path: "/main/data/tag",alias: "/tag",name: "tag",meta: {title: "分析",requireAuth: true}},{path: "/main/button",alias: "/button",name: "button",meta: {title: "标准列表",requireAuth: true,rights: ['view']},}]},{path: "/main/form",alias: "/form",name: "form",meta: {title: "表单",icon: "el-icon-document",requireAuth: true},children: [{path: "/main/form/validate",alias: "/validate",name: "validate",meta: {title: "基础表单",requireAuth: true}},{path: "/main/form/step",alias: "/step",name: "step",meta: {title: "分步表单",requireAuth: true}},{path: "/main/form/senior",alias: "/senior",name: "senior",meta: {title: "高级表单",requireAuth: true}}]},{path: "/main/list",alias: "/list",name: "list",meta: {title: "反馈",icon: "el-icon-chat-line-round",requireAuth: true},children: [{path: "/main/list/card",alias: "/card",name: "card",meta: {title: "卡片列表",requireAuth: true}}]},{path: "/main/dashbord",alias: "/dashbord",name: "dashbord",meta: {title: "分析",icon: "el-icon-monitor",requireAuth: true},children: [{path: "/main/dashbord/analysis",alias: "/analysis",name: "analysis",meta: {title: "分析页",requireAuth: true}}]}];

根据此数据动态渲染左侧菜单,数据在Login.vue中登录验证时得到,但是在Nav.vue中才使用,所以可以把数据用Vuex进行维护。

Vuex中代码:

将权限数据存储在sessionStorage中,并让其和Vuex中的数据保持同步,以解决刷新页面菜单消失的问题。

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {right_list: JSON.parse(sessionStorage.getItem("right_list") || "[]")},mutations: {set_right_list: (state, data) => {state.right_list = data;sessionStorage.setItem("right_list", JSON.stringify(data));}}
})

Login.vue中代码:

submitForm(form) {this.$refs[form].validate(valid => {if (valid) {this.$store.commit("set_right_list", right_list);sessionStorage.setItem("isLogin", 1);this.$router.push({ path: "/tag" });}});}

Nav.vue中代码:

<template><el-menuclass="el-menu-vertical-demo"background-color="rgb(0, 21, 41)"text-color="#fff"active-text-color="#ffd04b":default-active="this.$router.currentRoute.fullPath":unique-opened="true"@open="handleOpen"@close="handleClose":collapse="isCollapse"router><NavItem v-for="v in this.menu_list" :key="v.alias" :item="v" /></el-menu>
</template><script>
import NavItem from "./NavItem";
import { mapState } from "vuex";
export default {data() {return {menu_list: []};},methods: {handleOpen(key, keyPath) {console.log(key, keyPath);},handleClose(key, keyPath) {console.log(key, keyPath);}},props: ["isCollapse"],components: {NavItem},computed: {...mapState(["right_list"])},created() {this.menu_list = this.right_list;}
};
</script>

二、界面权限的控制:

如果用户没有登录,手动在地址栏输入管理界面地址,则应该直接跳转至登录页。

如果登录了但是输入了不存在的地址或者没有权限的地址,则应该跳转至特定页面。

如何判断是否登录?

sessionStorage.setItem("token", res.data.token);

什么时机?

路由导航守卫:

router.beforeEach((to, from, next) => {if (to.path == "/login") {if (sessionStorage.getItem("isLogin") === "1") {next("/tag");} else {next();}} else {if (to.meta.requireAuth && sessionStorage.getItem("isLogin") === "1") {next();} else if (!to.meta.requireAuth && sessionStorage.getItem("isLogin") === "1"){next("/tag");window.location.reload();} else {next("/login");}}
})

至此,已经实现用户必须登录才能查看管理页,但是如果用户没有相应的查看权限而在浏览器中直接输入无权限的地址怎么控制呢?

动态路由

登录成功之后,路由跳转之前添加,或者在刷新页面的时候进入路由导航守卫之前添加。

router.js:

import Vue from 'vue'
import Router from 'vue-router'const ruleMapping = {data: () => import("@/pages/statistics/Index"),tag: () => import('@/pages/statistics/Tag'),button: () => import('@/pages/statistics/StandardList'),form: () => import('@/pages/form/Index'),validate: () => import('@/pages/form/Validate'),step: () => import('@/pages/form/step'),senior: () => import('@/pages/form/senior'),list: () => import('@/pages/list/Index'),card: () => import('@/pages/list/CardList'),dashbord: () => import('@/pages/dashbord/Index'),analysis: () => import('../pages/dashbord/analysis')
}Vue.use(Router);let router = new Router({mode: 'hash',routes: [{path: '/',alias: '/',name: 'index',redirect: '/login'},{path: '/login',alias: '/login',name: 'login',component: () => import("@/pages/login/Index"),meta: {title: 'Login'}},{path: '/main',alias: '/main',name: 'main',redirect: '/tag',component: () => import("@/components/Main"),meta: {title: 'Main'},children: []}]
});export function initDynamicRoutes() {const currentRoutes = router.options.routes;const right_list = JSON.parse(sessionStorage.getItem("right_list"));try {right_list.forEach(item => {item.component = ruleMapping[item.name];item.children.forEach(c_item => {c_item.component = ruleMapping[c_item.name];})})currentRoutes[2].children = right_list;router.addRoutes(currentRoutes);} catch (error) {console.log(error);}
}// 判断是否登录
if (sessionStorage.getItem("isLogin") === "1") {initDynamicRoutes();
}export default routerrouter.beforeEach((to, from, next) => {if (to.path == "/login") {if (sessionStorage.getItem("isLogin") === "1") {next("/tag");} else {next();}} else {if (to.meta.requireAuth && sessionStorage.getItem("isLogin") === "1") {next();} else if (!to.meta.requireAuth && sessionStorage.getItem("isLogin") === "1"){next("/tag");window.location.reload();} else {next("/login");}}
})

其中:

if (sessionStorage.getItem("isLogin") === "1") {initDynamicRoutes();
}

解决刷新后不动态加载对应的权限页面的问题。

Login.vue:

submitForm(form) {this.$refs[form].validate(valid => {if (valid) {this.$store.commit("set_right_list", right_list);sessionStorage.setItem("isLogin", 1);initDynamicRoutes();this.$router.push({ path: "/tag" });}});}

三、按钮权限控制

在界面中,还得根据权限数据展示出可进行操作的按钮,比如删除、修改、增加,可以把该逻辑放在自定义指令中:

页面中添加权限代码:

<el-button type="primary" size="small" icon="el-icon-plus" @click="openAddDialog" v-permission="{action: 'add', effect: 'disabled'}">添加</el-button>

返回的路由中相应的权限信息:

{path: "/main/button",alias: "/button",name: "button",meta: {title: "标准列表",requireAuth: true,rights: ['view']},}

permission.js:

import Vue from 'vue'
import router from '@/router/router'Vue.directive("permission", {inserted: function(el, binding){const action = binding.value.action;const current_right = router.currentRoute.meta.rights;if(current_right){if(current_right.indexOf(action) === -1){const type = binding.value.effect;if(type === "disabled"){el.disabled = true;el.classList.add("is-disabled");} else {el.parentNode.removeChild(el);}}}}
})

main.js中引入指令文件:

import './utils/permission.js'
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'
import store from './vuex/store'
import router from './router/router.js'
import './utils/permission.js'import echarts from 'echarts'import axios from 'axios'
Vue.prototype.$axios = axiosVue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(echarts)
Vue.prototype.$echarts = echarts/* eslint-disable no-new */
new Vue({el: '#app',router,store,components: { App },template: '<App/>'
})

四、请求和响应权限的控制:

如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成启用状态,此时发的请求应该被前端所拦截。

除了登录,其它所有请求都要带上token,这样服务器才可以鉴别你的身份。

HTTP.interceptors.request.use(function (config) {  const current_url = config.url;if(current_url !== "login"){config.headers.TOKEN = sessionStorage.getItem('TOKEN');}return config;
}, function (error) {return Promise.reject(error);
});

如果发出了非权限内的请求,应该直接在前端访问组织,虽然这个请求发到服务端也会被拒绝:

import axios from 'axios'
import router from '@/router/router'let _this = this;const action_mapping = {get: 'view',post: 'add',put: 'edit',delete: 'delete'
}HTTP.interceptors.request.use(function (config) {const current_url = config.url;if(current_url !== "login"){config.headers.TOKEN = sessionStorage.getItem('TOKEN');const action = action_mapping[config.method];const current_right = router.currentRoute.meta.rights;if(current_right && current_right.indexOf(action) === -1){alert("没有权限");return Promise.reject(new Error("没有权限!"));}}return config;
}, function (error) {return Promise.reject(error);
});

Vue中权限控制完全实现相关推荐

  1. vue 按钮 权限控制

    vue 按钮 权限控制 前言 在日常项目中,会碰到需要根据后台接口返回的数据,来判断当前用户的操作权限.必须当有删除权限时,就显示删除按钮.没有这个权限时,就不显示或者删除这个按钮.通过查找资料,通过 ...

  2. 《前端》权限链接--vue前端权限控制方案详解附demo_feiyu_may的博客-CSDN博客_vue 前端权限

    前端权限控制 - 潘正 - 博客园  https://www.cnblogs.com/guchengnan/p/11800947.html vue前端权限控制方案详解附demo_feiyu_may的博 ...

  3. ASP.NET MVC中权限控制的简单实现

    1.重写AuthorizeAttribute类,用自己的权限控制逻辑重写AuthorizeCore方法 public class MyAuthorizeAttribute : AuthorizeAtt ...

  4. 文档管理系统中权限控制实现方案

    整体思路 文档管理的权限控制与常规的功能权限和数据权限都不同,有其自己的特色,异常复杂. 1.权限项相对固化,对于文件夹,有创建.删除.更名.查看4个操作项:对于文件,则通常有上传.下载.删除.更名. ...

  5. Vue 页面权限控制(一)

    目录 前言 一.路由元信息和beforeEach() 1.路由元信息 2.beforeEach() 二.权限管理 1.路由比较少的情况 2.多路由-遍历to.matched 总结 前言 1.如果您有V ...

  6. 基于Vue实现后台系统权限控制

    原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue这类双向绑定框架做后台系统再适合不过,后台系统相比普通前端项目除了 ...

  7. lin-cms-dotnetcore.是如何方法级别的权限控制(API级别)的

    方法级别的权限控制(API级别) Lin的定位在于实现一整套 CMS的解决方案,它是一个设计方案,提供了不同的后端,不同的前端,而且也支持不同的数据库 目前官方团队维护 lin-cms-vue,lin ...

  8. 后台系统的权限控制与管理

    以下内容源于对该视频的学习 前端面试官必问系列-后台系统的权限控制与管理[完结] 目录 前端权限控制思路 vue的权限控制与实现 菜单的控制 界面的控制 按钮的控制 请求和响应的控制 总结 前端权限控 ...

  9. authorize如何控制多个角色权限】_lincmsdotnetcore.是如何方法级别的权限控制(API级别)的...

    方法级别的权限控制(API级别) Lin的定位在于实现一整套 CMS的解决方案,它是一个设计方案,提供了不同的后端,不同的前端,而且也支持不同的数据库 目前官方团队维护 lin-cms-vue,lin ...

最新文章

  1. java中的运算符_java中的运算符
  2. 参加noip有必要先学python吗_参加 NOIP 需要学些什么,做哪些准备,用哪些书?...
  3. fopen()及相关函数使用
  4. SQL server 2012 数据库还原操作
  5. Windows安装CUDAcuDNNanaconda
  6. tensorflow之train.get_checkpoint_state
  7. 系统学习机器学习之距离的度量(二)--DTW
  8. 【win10 专业版】 重装系统、激活
  9. Codeforces Round #459 (Div. 1) B. MADMAX(dp+博弈)
  10. Win10中文输入法加入美式英文键盘并默认英文键盘
  11. Java实验-课程设计报告一:个人银行账户管理系统SavingAccountManageSystem-具体文档+源码...
  12. TTL 传输中过期,内部网络环路
  13. 解读BLM业务领先模型中的业务设计
  14. 电脑开机太慢?这5个方法瞬间提升你的电脑速度
  15. 又一巨头告急!曾年赚500亿,如今连房租都付不起!
  16. mysql实现postgres中pg_size_pretty函数
  17. ybt1003:对齐输出
  18. gvim for verilog简易配置
  19. 中文字符乱码的原因及解决办法
  20. 一杯睡前牛奶,会不会让年轻人的失眠有尽头?

热门文章

  1. 蔬菜配送APP开发基本功能
  2. python字典可以对键信息赋值吗_python字典键操作
  3. Ubuntu18.04安装安装ROS2-Dashing
  4. pfsense远程管理
  5. 华为m3现在还能用吗_现在买华为M3还值得吗?这个时间段,M4是不是快出来了?好纠结哦...
  6. [TIST 2022] No Free Lunch Theorem for Security and Utility in Federated Learning
  7. webbench 下载_Webbench的安装和使用
  8. android t类型参数,类型参数T是隐藏类型T(The type parameter T is hiding the typ
  9. 相机demo的java部分
  10. 这些大学虽然不是985,却备受国企青睐考上就业不愁