目录

1、注册vue-router

2、声明 默认路由 和权限路由

3、用vuex实现全局登录、退出登录等方法

4、用vuex模块单独写权限路由的判断

5、监听路由跳转实现动态加载权限菜单


需要用到动态加载路由,router.addRouters()来动态的挂载路由,接下来我们来一步一步分解步骤。

1、注册vue-router

创建 router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './router'// hack router push callback
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location, onResolve, onReject) {if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)return originalPush.call(this, location).catch(err => err)
}Vue.use(VueRouter)export default routes

2、声明 默认路由 和权限路由

创建router/router.js,生成全局路由变量


import VueRouter from 'vue-router'// 路由基础表
export const routes = [// 起始页{path: '/',name: 'index',component: () => import('@/views/index/')},// 首页{path: '/home',name: 'home',component: () => import('@/views/home/')},// 登录页{path: '/login',name: 'login',component: () => import('@/views/login/')},{path: '/error',component: () => import('../views/404/'),name: 404},{path: "*", // 此处需特别注意置于最底部redirect: "/error"}
]// 路由动态菜单 (需权限调控)
export const asyncRouteMap = [// 报表页{path: '/report',name: 'report',component: () => import('@/views/report/')},// 报表页{path: '/report2',name: 'report2',component: () => import('@/views/report2/')},
]// 因为可以动态的挂载路由,但是不能动态删除路由。所以才考略到,
// 在需要动态清空动态挂载路由的话,直接将一个新的路由对象赋值给旧的路由对象,这样就可以达到动态清除的工作
const createRouter = () => new VueRouter({routes})const router = createRouter()// 调用该方法动态清除动态挂载路由
export function resetRouter () {const newRouter = createRouter()router.matcher = newRouter.matcher // reset router
}export default router

3、用vuex实现全局登录、退出登录等方法

创建 store/index.js,里面装载 用户登录 、获取权限、 退出登录清空权限、存放token和权限菜单等全局变量和方法。

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex);import { resetRouter } from '../router/router'
import router from '../router/'import { userInfo } from '@/api/login'// 引入权限模块
import permission from './permission'export default new Vuex.Store({//所有的数据都放在state中state: {roles: [],token: localStorage.getItem('token') || ''},//操作数据,唯一的通道是mutationsmutations: {// 将获取到的token存储到本地SET_TOKEN (state, token) {state.token = tokenlocalStorage.setItem('token', state.token)},// 将获取到的roles粗出到本地SET_ROLES (state, roles) {state.roles = roleslocalStorage.setItem('roles', JSON.stringify(state.roles))}},// 可以来做异步操作,然后提交给mutations,而后再对state(数据)进行操作actions: {// 用户登录userLogin ({ commit }, data) {// 返回一个异步回调,promisereturn new Promise(async (resolve, reject) => {// 调用登录接口 let res = await userInfo({password: data.password, username: data.username})// 如果登录成功if (res.status === 200) {// 调用mutations中的方法,将token存储到本地中commit('SET_TOKEN', res.data.token)resolve(res.data)} else {reject(res.message)}})},// 根据用户的token获取用户的个人信息,里面包含了权限信息getUserInfo ({ state, commit }) {// 返回一个异步回调,promisereturn new Promise((resolve, reject) => {// 获取有无缓存权限菜单let roles = localStorage.getItem('roles') ? JSON.parse(localStorage.getItem('roles')) : []// 如果已有权限菜单则不必再去请求接口if (roles.length > 0) {commit('SET_ROLES', roles)// 调用用户权限接口方法获取数据 (看自己项目,有的在登录接口则返回,有的在用户信息接口)// 将获取到的信息放到数组中存储 (这里自定义)} else {let data = ['report']commit('SET_ROLES', data)}resolve(state.roles)})},// 退出登录userLogout ({ commit }) {// 清空权限菜单commit('SET_ROLES', [])// 清空tokencommit('SET_TOKEN', '')// 清除路由resetRouter()// 跳转到登录菜单router.push({path: '/login'})}},// vuex的计算属性getters: {// 将用户数据放到计算属性中,一旦数据发生变化,可以重新计算roles (state) {return state.roles},token (state) {return state.token}},// 模块modules: {permission}
})

4、用vuex模块单独写权限路由的判断

创建 store/permission.js,编写 GenerateRoutes 方法判断获取有权限的路由, hasPerMission 函数用于判断权限主要核心函数。

GenerateRoutes 方法由 utils/global.js 调用,传进来判断权限的数组格式为自定义的 ['report'] 之类,按自己需求去改写,权限的获取在 store/index 的getUserInfo函数。

// 引入基础路由
import { routes, asyncRouteMap } from '../router/router' // 用来筛选后端返回来的权限数据,和权限路由中的meta里面的数据匹配,匹配成功返回true,失败为falsefunction hasPerMission (roles, route) {if (route && route.name) {return roles.indexOf(route.name) > -1} else {return true}
}const permission = {state: {routers: routes,addRouters: []},mutations: {// 将匹配成功的权限路由拼接到公共路由中SET_ROUTERS (state, routers) {state.addRouters = routersstate.routers = routes.concat(routers)}},actions: {// 对后台返回来的权限和动态路由权限匹配GenerateRoutes ({ commit }, data) {// 返回一个异步回调promisereturn new Promise((resolve, reject) => {// 遍历权限路由数组const accessedRoutes = asyncRouteMap.filter(v => {// 之后就是调用hasPerMission函数对象权限动态路由和后台返回的用户权限进行严格匹配if (hasPerMission(data, v)) {// 判断是否有权限路由是否有子路由,有子路由继续遍历 (只做到二级)if (v.children && v.children.length > 0) {v.children = v.children.filter(child => {// 对权限子路由和后台返回的用户权限数据,在进行匹配,匹配成功返回if (hasPerMission(data, child)) {return child}// 失败返回falsereturn false})// 并且要把权限的父路由返回来,不光要把权限子路由返回,无论权限子路有还是没有,都应该把权限父路由返回来return v} else {// 权限父路由匹配成功返回return v}}// 如果每一个判断都没有进,说明该用户没有任何权限,返回falsereturn false})commit('SET_ROUTERS', accessedRoutes)resolve()})}},getters: {// 只要权限路由数组发生变化就重新计算addRouters (state) {return state.addRouters}}}export default permission

5、监听路由跳转实现动态加载权限菜单

创建 utils/global,监听路由的跳转后,

判断是否 有token,没有则跳向登录页,

如果有token,则进行用户权限获取 (在store/index下的getUserInfo函数),

获取完权限进入 store/permission的GenerateRoutes函数 进行获取符合条件的路由,

再通过addRoutes方法加载路由

// 先把路由和vuex引进来使用
import router from '../router'
import store from '../store'const whiteList = ['/login'] // 不重定向白名单router.beforeEach((to, from, next) => {if (store.getters.token) {// 判断如果是去登陆页面的话,返回主页,不让他返回登录页if (to.path === '/login') {next({ path: '/home' })} else {// 否则判断一下用户的个人信息是否已经拉取完毕if (store.getters.roles.length === 0) {// 拉取用户个人信息store.dispatch('getUserInfo').then(data => {// 拿到用户后台返回的权限数据const roles = data// 调用 permission.js方法中的GenerateRoutes方法,将后台返回的用户的权限数据,传递回去进行筛选处理store.dispatch('GenerateRoutes', roles).then(() => { // 生成可访问的路由表// 将筛选的权限路由数组动态挂载router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表next({ ...to, replace: true }) // hack方法 确保addRoutes添加完成})}).catch(error => {// 验证失败重新登陆next({ path: '/login' })})} else {next() // 当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的页面会自动进入404页面}}} else {// 如果已经去了登陆页面了,就不需要再next到登陆页面了,这就是重定向白名单if (whiteList.indexOf(to.path) !== -1) {next()} else {next('/login') // 否则全部重定向到登录页}}
})

github地址:https://github.com/banxia1609/framehttps://github.com/banxia1609/frame

vue系统权限(动态加载路由方式)相关推荐

  1. vue 项目如何实现动态加载路由?

    一般来说,vue项目实现动态路由的方式大体可分为两种: 前端把路由写好,登录的时候根据用户的角色权限来动态展示路由,(前端控制路由) 后台接口提供当前用户对应权限的路由表,前端通过调接口拿到后处理(后 ...

  2. vue动态加载路由的实现

    动态加载路由的实现 vue后台管理之动态加载路由 vue路由动态加载

  3. nodejs动态加载路由

    Nodejs动态加载路由,Nodejs遍历目录,Nodejs路由工具 工具来源: Nodejs需要手动加载路由文件,如果一个个添加,项目逐渐扩大,比较麻烦. 尤其在项目route目录下,增加模块文件夹 ...

  4. reactjs通过lazy函数配合import函数动态加载路由组件

    路由组件的lazyLoad //1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包const Login = lazy(()=>i ...

  5. Vue文件内动态加载JS

    Vue文件内动态加载JS let jsUrl = 'https://code.jquery.com/jquery-3.4.1.min.js' // JS地址 let jqueryJs = decode ...

  6. 【Python_PySide2学习笔记(一)】PySide2动态加载UI方式,重写关闭窗体事件

    ** PySide2设置关闭提示窗口:动态加载UI方式,重写关闭窗体事件 ** ** 前言 ** 转载:https://blog.csdn.net/qq_44703282/article/detail ...

  7. vue 动态修改后端请求_vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单...

    一. 前言 本篇基于 有来商城 youlai-mall微服务项目,通过对vue-element-admin的权限菜单模块理解个性定制其后台接口,实现对vue-element-admin工程几乎不做改动 ...

  8. vue组件的动态加载

    ​ 平常的vue项目开发,已经很难遇见一千行,甚至几千行代码的页面了,毕竟大家都会去拆分组件.但如果一个页面需要通过十几个组件或者几十个组件中的某几个组件去排列组合渲染,此时用动态加载就很有必要了. ...

  9. HTML5动态加载资源方式,动态加载JavaScript文件的3种方式

    以下是遇到的几种动态加载JavaScript文件的方式,持续更新中... 一.使用document.write/writeln()方式 该种方式可以实现js文件的动态加载,原理就是在重写文档流,这种方 ...

最新文章

  1. [日记]一个人去散步
  2. php的内存分配还是很智能的
  3. java中override快捷键_【基础回溯1】面试又被 Java 基础难住了?推荐你看看这篇文章。...
  4. python怎么调用方法_python中怎么调用自己的方法
  5. checkedListBox使用例子
  6. javascript --- 利用节点关系访问HTML元素
  7. wince ./configure
  8. ctypes python3.7_装新的python3.7时ModuleNotFoundError: No module named '_ctypes'
  9. python pptp链接_pptp-client连接设置
  10. 牛客(3)从尾到头打印链表
  11. SLAM学习笔记-------------(六)非线性优化
  12. 解决办法:对avcodec_parameters_from_context未定义的引用
  13. paip.项目文件同步-分支和合并总结V2012.9.23
  14. java省市区_JAVA省市区地址解析 原创
  15. TCP/IP路由技术第一卷静态路由知识回顾
  16. CUD表单验证+增删改查
  17. 单片机测量脉宽c语言程序,利用51系列单片机定时器功能实现测量脉冲宽度
  18. Right-BICEP 测试四则运算程序
  19. it行业java_转行IT行业前景怎么样 为什么要选择Java开发
  20. 为分布式做准备吧——调用链原理

热门文章

  1. 昆仑通泰(MCGS)官方资料
  2. 在Java中什么是IoC和DI?DI是如何实现的?
  3. 27岁转行软件测试,成功虽晚但不迟,写给跟我一样迷茫的人。
  4. 一个没有任何基础的人,怎样入门计算机,成为程序员?
  5. 建群网培PMP每日一练2020-7-29
  6. au如何关闭预览编辑器_Garageband怎么打开关闭音频编辑器 操作方法介绍
  7. 添加超声波障碍图层并用rbx1仿真
  8. python学生数据完善程序_「Python」每日一练:学生数据完善程序
  9. 52单片机与MH-Sensor-Series模块使用简单检测车轮转速
  10. 微信看一看内容来源哪里?看一看推荐规则是什么?怎么赚钱?