vue2项目中权限控制


页面访问权

在登陆的时候确定权限

  • 在定义路由的时候区分静态路由和动态路由,静态路由是所有用户都可以访问的,动态路由只有有权限的时候才可以访问,后续可以通过router.addRoutes()添加拥有的权限路由
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

/* Layout */
import Layout from '@/layout'

import approvalsRouter from './modules/approvals'
import departmentsRouter from './modules/departments'

/* 动态路由 */
export const asyncRoutes = [
  approvalsRouter,
  departmentsRouter
]

/* 静态路由 */
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' }
      }
    ]
  }
]

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

//重置router的方法,需要在退出的时候重置router,否则下一个人登陆后也能访问上一个人的路由
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

const router = createRouter()

export default router

  • 右侧导航项是遍历router.options.routes的,但router.addRoutes()调用后并不能更改router.options.routes的值,只能控制添加路由的跳转,所以就需要使用vuex来存储拥有的所有路由
//store 的perimission模块
import { constantRoutes, asyncRoutes } from '@/router'

const state = {
  routes: constantRoutes // 路由表
}
const mutations = {
  setRoutes(state, newRoutes) {
    state.routes = [...constantRoutes, ...newRoutes]
  }
}
const actions = {
  filterRoutes(context, menus) {
    const routes = []
    menus.forEach(key => {
      routes.push(...asyncRoutes.filter(item => item.name === key))
    })
    context.commit('setRoutes', routes)
    return routes  //在路由拦截器中调用这个actions,修改store中routes,store中routes的值是用来遍历得到右侧导航栏的,return的值是router.addRoutes()的参数,当然也可以使用store中俄 routes,但是没有return来的方便
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

  • 在路由全局前置后卫中做权限拦截,获取用户资料,用户资料中roles是当前用户的权限数据,其中roles.menus是用户的页面访问权信息,roles.ponits是用户的按钮点击权的信息

/*
 * @User: <jf>
 * @Date: 2021-09-09 19:35:50
 */
import router from '@/router'
import store from '@/store'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

const whiteList = ['/login', '/404']

router.beforeEach(async(to, from, next) => {
  NProgress.start()
  if (store.getters.token) {
    if (to.path === '/login') {
      next('/')
    } else {
      if (!store.getters.userId) {
        try {
          // 获取用户信息,用户信息使用vuex管理的  roles.menus 是当前用户所拥有的 页面访问权限点 
          const { roles } = await store.dispatch('user/getUserInfo')
          const routes = await store.dispatch(
            'permission/filterRoutes',
            roles.menus
          )
          router.addRoutes([
            ...routes,
            { path: '*', redirect: '/404', hidden: true }
          ]) // 此时用户可以访问所得静态路由和筛选出来当前用户所有拥有的动态路由
          next(to.path)
        } catch (error) {
          console.log(error)
        }
      } else {
        next()
      }
    }
  } else {
    if (whiteList.some(x => x === to.path)) {
      next()
    } else {
      next('/login')
    }
  }
  NProgress.done()
})
router.afterEach((to, from, next) => {
  NProgress.done()
})

  • 在便用生成右侧菜单的时候使用store中的routes数据,而不要使用router.options.routes的数据
 computed: {
    ...mapGetters(["routes"]),
    routes1() {
      return this.$router.options.routes; //不要使用这个数据,这个并会因为有router.addRoutes()的调用而改变
    }
	}

退出重置路由和重置store中的路由数据

const actions = {
  // 登陆
  async login(context, data) {
    const res = await login(data)
    context.commit('setToken', res)
    setTimeStamp()
  },
  //退出 清除 token和用户资料
  logout(context) {
    context.commit('removeToken')
    context.commit('removeUserInfo')
    // 重置路由
    // resetRouter()
    // context.commit('permission/setRoutes', [], { root: true })
  }
}

按钮点击权

  • 在路由全局前置后卫中做权限拦截,获取用户资料,用户资料中roles是当前用户的权限数据,其中roles.menus是用户的页面访问权信息,roles.ponits是用户的按钮点击权的信息,每一个按钮都一个标识,定义一个方法根据roles.points中的按钮权限点返回true/false,true表示可以点击
// 定义一个mixin方法,全局注册
import store from '@/store/index'
export default {
  methods: {
    checkPermission(key) {
	 //userInfo是用户的资料
      const { userInfo } = store.state.user
      if (userInfo.roles && userInfo.roles.points) {
        return userInfo.roles.points.some(item => item === key)
      }
      return false
    }
  }
}

// 在页面中调用mixin的方法,将方法返回的结果给button的disabled属性
      <el-button :disabled="!checkPermission('add-depts')" @click='add'>添加</button>


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM