vue 权限管理

一、目的

    前端根据后台给的用户角色权限,渲染对应的导航栏

二、实现步骤

  1. 创建vue实例的时候将vue-router挂载,挂载一些登录的和不需要权限的公用页面
  2. 用户登录后,获取权限role,将role和路由表每个页面的需要的权限做对比,获取用户最终可访问的路由表
  3. 在导航守卫获取用户权限,存到vuex里面,每次跳转进行判断,并且调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
  4. 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

三、具体实现

1. 路由添加

PS: 一定要把{path: '*', redirect: '/404', hidden }加在路由最下面,不然后面页面一刷新就找不到路由,会出现404页面

router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

import Layout from '@/layout'

export const constantRoutes = [
  // 基础路由
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [
      {
        path: 'dashboard',
        name: 'Dashboard',
        component: () => import('@/views/dashboard/index'),
        meta: { title: '首页', icon: 'dashboard' }
      }
    ]
  }
]

export const allMenus = [
  // 权限路由
  {
    path: '/form',
    component: Layout,
    children: [
      {
        path: 'index',
        name: 'Form',
        component: () => import('@/views/empty/index'),
        meta: { title: '账号管理', icon: 'form' }
      }
    ]
  },
  // 404 page must be placed at the end !!!
  { path: '*', redirect: '/404', hidden: true }
]

const createRouter = () =>
  new Router({
    // mode: 'history', // require service support
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRoutes
  })

const router = createRouter()

export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router

 

2、获取用户权限

在导航守卫获取用户权限,存到vuex里面,每次跳转进行判断

permission.js

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
import { constantRoutes } from '@/router'

NProgress.configure({ showSpinner: false }) // NProgress Configuration

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

/* eslint-disable */
router.beforeEach(async (to, from, next) => {
  NProgress.start()

  document.title = getPageTitle(to.meta.title)

  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      if (!store.getters.limit) {
        store
          .dispatch('Getpermissions')
          .then(resp => {
            const menus = constantRoutes
            router.options.routes = [...menus, ...store.getters.limit]
            router.addRoutes(store.getters.limit)
            next({ ...to, replace: true })
          })
          .catch(err => {
            console.log(err)
            store.dispatch('FedLogOut').then(() => {
              Message.error(error.message || '获取用户权限失败,请重新登录')
              next({ path: '/' })
            })
          })
      } else {
        next()
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

 

3、权限匹配和存储

store/modules/permission.js

import { getLimit } from '@/api/user'
import { allMenus } from '@/router'

function filterMenus(menus, gnbmArr) {
  const finalRouter = menus.filter(menu => {
    if (gnbmArr.indexOf(menu.name) >= 0) {
      if (menu.children && menu.children.length) {
        menu.children = filterMenus(menu.children, gnbmArr)
      }
      return true
    } else {
      return false
    }
  })
  return finalRouter
}
const state = {
  limit: null,
  allMenus: []
}
const mutations = {
  SET_LIMIT: (state, limit) => {
    console.log(limit)
    state.limit = limit
  }
}
const actions = {
  Getpermissions({ commit }) {
    return new Promise((resolve, reject) => {
      getLimit().then(resp => {
        const gnbmArr = resp.data.map(item => {
          return item.gnbm
        })
        const finalMenus = filterMenus(allMenus, gnbmArr)
        commit('SET_LIMIT', finalMenus)
        resolve()
      })
    })
  }
}
export default {
  state,
  mutations,
  actions
}

 

4、侧边栏

使用了vue-element-admin的侧边栏,通过computed获取侧边栏

  computed: {
    ...mapGetters(['sidebar']),
    routes() {
      return this.$router.options.routes
    }
  },

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值