Vue权限管理


这些天XX老师带着做了一个项目实战,把Vue权限管理相关内容整理一下,目的有二:其一,整理整个过程的逻辑思路;其二,备日后参考改进。

思路

  1. 后端返回需展示数据
  2. 后端只返回用户权限

后端返回需展示数据(只概述思路)

  1. 后端返回数据实例
    其中:title=>面包屑 component =>方便进行组件拼接 icon =>导航栏图标
const routesdata = [
{path:'/index',name:'index',title:'首页',component:'index',icon:'a'},
{path:'/loan-input',name:'loan-input',title:'贷款申请',component:'loan-input',icon:'icona'},
{path:'/index',name:'/index',title:'首页',component:'index',icon:'a'},
]
  1. 创建routes数组,遍历routesdata数组,并按照标准路由格式,追加到routes中,最后形成一个和静态路由相似样式的数组对象。
  2. 再利用router.addRoutes方法,把生成的路由数组对象routes追加到router中
    感觉这种方式需要前端和后端的沟通,前端要明确自己需要那些数据,后端才能进行相应的传值。

后端只返回用户权限

后端只需要返回用户权限,剩下的数据筛选过滤都由前端来完成。需要修改的有三个文件:
【路由】【Vuex】【导航栏Nav】

  1. 设置两个存放路由的数组对象,分别是路由的常规配置和异步路由,其中异步路由对象需要添加一个权限参数roles
  2. 设置路由拦截,在路由跳转之前,获取用户权限信息,然后追加路由和设置导航栏的递归

方式二实现步骤

1.router/index.js文件

//两个路由数组定义
//常规配置
export const constantRoutes = [
{
    path: '/',
    redirect:'/home'
  },
  {
    path: '/login',  //登录
    name: 'login',
    component: () => import('../views/login/index')
  },
  {
    path: '/home',  //布局页
    name: 'home',
    redirect: '/index',
    meta: {title: '首页',roles:['input','approve']},
    component: () => import('../layout/index'),
  }
]
//异步路由   注意:为meta添加了roles对象,用于路由过滤,其中input和approve必须和后端返回权限一致。
export const asyncRoutes = [   //异步路由  
  {
    path: '/index',   //首页
    name: 'index',
    meta:{title:'首页',roles: ['input','approve']},
    component: () => import('../views/home/index')
  },
  {
    path: '/loan-input',   //贷款申请
    name: 'loan-input',
    meta:{title:'贷款申请',roles: ['input']},
    component: () => import('../views/loan-input/index')
  },
  {
    path: '/input-manager',
    name: 'input-manager',
    meta: { title: '申请管理' ,roles: ['input']},
    component: () => import('../views/input-manager/index'),
  },
  {
    path: '/loan-approve',   //贷款审批
    name: 'loan-approve',
    meta:{title:'贷款审批',roles: ['approve']},
    component: () => import('../views/loan-approve/index'),
    children:[
      {
        path: '/loan-approve/first',   //初审
        name: 'first',
        meta:{title:'初审'},
        component: () => import('../views/loan-approve/first')
      },
      {
        path: 'end',   //终审
        name: 'end',
        meta:{title:'终审'},
        component: () => import('../views/loan-approve/end')
      },
    ]
  },
  {
    path: '/contract',
    name: 'contract',
    meta: { title: '标的管理' ,roles: ['approve']},
    component: () => import('@/views/contract/index'),
  },
  {
    path: '/permission',
    name: 'permission',
    meta: { title: '权限管理'},
    component: () => import('@/views/permission/index'),
    children:[
      {
        path: '/permission/list',
        meta: { title: '列表展示' },
        component: () => import('@/views/permission/list'),
      }
    ]
  },
]
const router = new VueRouter({
  routes:constantRoutes     //这里只赋值constantRoutes
})

2.permission.js文件
功能:进行路由拦截

router.beforeEach(async(to,from,next)=>{
    if(to.path=='/login'){
        next();
    }else {
        var getRoles = store && store.getters.roles && store.getters.roles.length>0;
        if(getRoles) {
            next();
        }else {
            //获取详情信息,发送请求
            var  {roles} = await store.dispatch('getInfo');
            //取出角色
            var rolesName= roles.map(v=>v.name);
            //过滤角色
            var filterRoutes = await store.dispatch('GENERATEROUTES',rolesName);
            //动态添加
            router.addRoutes(filterRoutes);
            if(roles) {
                next({path:to.path})
            }else {
                next({path:'/login'})
            }
        }
    }
})

3.store中的permission.js:进行角色过滤

import {constantRoutes,asyncRoutes} from '@/router'

function filterAsyncRouter(routes,name){  //过滤角色
  var data = routes.filter(route=>{
    return route.meta && route.meta.roles && name.some(v=>route.meta.roles.includes(v))
  })
  return data;
}

const state={
  routes:[]  //动态路由
};
const getters={
  get_routes:state=>state.routes,
};
const actions={
  GENERATEROUTES({commit,state},rolesName){   //通过角色来过滤路由
    return new Promise((resolve, reject) => {
      var _routes; //
      let home = constantRoutes.filter(v=>v.path=='/home')[0];   //
      home.children = []; //清除
      if(rolesName.includes('administrator')){  //是否是管理员
        home.children = asyncRoutes;
      }else {
        let filterRouter = filterAsyncRouter(asyncRoutes,rolesName);
        home.children = filterRouter;
      };
      _routes = [home] || [];
      commit('SET_ROUTES', _routes);
      resolve(_routes)
    })
  },
};
const mutations={
  SET_ROUTES:(state,routes)=>{
    state.routes = routes;
  }
};

export default{
  state,
  getters,
  mutations,
  actions
}

4.设置导航栏

NavMenu.vue
<template>
      <el-aside width="200px" class="aside">
      <!-- 左侧导航 -->
      <el-menu
      :default-active="$route.path" exact
      router> 
      <sideItem v-for="v in get_routes[0].children" :key="v.path" :item="v" :path="v.path"/>
      </el-menu>
    </el-aside>
    
</template>

<script>
import {mapGetters} from 'vuex'
import sideItem from './sideItem'
export default {
  data(){
    return {

    }
  },
  computed:{
    ...mapGetters(['get_routes'])
  },
  components:{
    sideItem
  }
}
</script>

//sideItem.vue
<template>
  <div>
      <!-- 没有子级 -->
      <el-menu-item :index="path" v-if="!item.children">
        <i class="el-icon-setting"></i>
        <span slot="title">{{item.meta.title}}</span>
      </el-menu-item>


      <!-- 有子级 -->
      <el-submenu :index="path" v-else>
        <template slot="title">{{item.meta.title}}</template>
        <sideItem v-for="child in item.children" :key="child.path" :item="child" :path="getPath(child.path)"/>
      </el-submenu>

  </div>
</template>

<script>
import _path from 'path'
export default {
  name:'sideItem',
  data(){
    return {

    }
  },
  props:["item","path"],
  methods:{
    //_path.resolve('a/b','./c')    '/a/b/c'
    getPath(url){
      return _path.resolve(this.path,url);
    }
  }
}
</script>








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值