vue 实现权限控制 动态路由 按钮控制

本文详细介绍了如何在前端实现动态路由控制,通过后端返回的用户权限列表,动态生成用户可访问的菜单,并在不满足权限时跳转至404页面。同时,还展示了如何实现动态按钮的权限判断,使用mixins组件实现权限控制,确保用户只能看到和操作他们被授权的内容。
摘要由CSDN通过智能技术生成

前提:需要前后端一起配合完成;
动态路由的控制
在登录接口,后端返回当前用户拥有的权限;
请添加图片描述
拿到 之后 我们利用这个实现动态路由;我们把他存放到vuex中;方便后续或许这个权限列表;

在前端定义路由的过程中,需要将每个路由对象的id和后端返回的这个写成一致;

{
    path: '/tasks',
    name: 'xx管理',
    icon: 'icon-task',
    children: [
      {
        path: '/tasks',
        name: 'xxx',
        permissionId: 3,
        component: 'task/Task.vue',
        meta: {
          keepAlive: true
        },
        nested: [
          {
            path: '/tasks/taskRecord',
            name: 'xx详情',
            permissionId: 4,
            hide: true,
            component: 'task/taskRecord/TaskRecord.vue'
          }
        ]
      }
    ]
  },

这时候就可以实现动态了,同时 不满足的页面 让他跳转到404页面,防止用户输入没有权限的页面;

function checkPermissions (navs: Nav[], permissionListIds: number[]) {
  return navs.map(nav => {
    if (nav.nested && permissionListIds.indexOf(nav.permissionId) !== -1) {
      // 给任务详情 展示与否
      const nestedNavs = checkPermissions(nav.nested, permissionListIds);
      return {
        ...nav,
        nested: nestedNavs
      };
    }
    if (permissionListIds.indexOf(nav.permissionId) !== -1) {
      return nav;
    }
    return {};
  }).filter(x => x.name);
}




  const permissionList: PermissionModel[] = await store.getters['auth/permission'];
  const permissionListIds = permissionList.filter(item => {
    return item.operational[0].select; // 数组第一个代表的是查看功能
  }).map(item => item.id);

  // 得到权限对应的
  const allNavs: Nav[] = navs.map(nav => {
    if (nav.children) {
      const childNavs = checkPermissions(nav.children, permissionListIds);
      if (childNavs.length) {
        return {
          ...nav,
          children: childNavs
        };
      }
    } else {
      return nav.name === '404' ? nav : permissionListIds.indexOf(nav.permissionId) !== -1 ? nav : null;
    }
  }).filter(x => x);

至此 上面实现了动态路由;

下一步 实现动态按钮,由于我们是封装了一个按钮的组件,所以写了一个mixins; 需要的页面是用这个就可以了;需要传入id或者name;name是用于详情(按钮–跳转三级页面的时候,看他路由的查看功能)
hasPermission就是用来判断这个有没有权限的;其他页面写一个计算属性 即可 但他有自己的disabled的时候 先用自己的

import Vue from 'vue';
import { Component, Watch, Prop } from 'vue-property-decorator';
import { PermissionModel } from '@sarai/model/userManage';

@Component
export default class Permission extends Vue {
  @Prop({
    type: Number,
    required: false
  })
  protected permissionId!: number;

  @Prop({
    type: String,
    required: false
  })
  protected permissionName!: string;

  protected hasPermission = false;
  protected permissionIdByPage?: number|null;

  private async setHasPermission () {
    const permissionList: PermissionModel[] = await this.$store.getters['auth/permission'];

    // 如果传入的是name 例子:任务详情
    if (this.permissionName) {
      const routePermission = permissionList.filter(item => item.name === this.permissionName)[0];
      this.hasPermission = !routePermission.operational[0].select;
      return;
    }

    const navs = this.$store.getters['nav/navsList'];

    const routePermissionId = navs.map(item => {
      if (item.children) {
        return item.children.filter(clItem => clItem.path === this.$route.path)[0] || item.children.map(childrenItem => {
          return childrenItem.nested && childrenItem.nested.filter(nestedItem => nestedItem.path === this.$route.path)[0];
        })[0];
      } else {
        return item.path === this.$route.path;
      }
    }).filter(x => x)[0].permissionId;

    const routePermission = permissionList.filter(item => item.id === routePermissionId)[0]; // 路由
    this.hasPermission = !(routePermission.operational.filter(item => item.id === this.permissionIdByPage || item.id === this.permissionId)[0].select); // 改操作是否有权限
  }

  @Watch('permissionId', { immediate: true })
  private async permissionIdChange () {
    if (!this.permissionId) {
      return;
    }
    this.setHasPermission();
  }

  @Watch('permissionName', { immediate: true })
  private async permissionNameChange () {
    if (!this.permissionName) {
      return;
    }
    this.setHasPermission();
  }

  @Watch('permissionIdByPage', { immediate: true })
  private async permissionIdByPageChange () {
    if (!this.permissionIdByPage) {
      return;
    }
    this.setHasPermission();
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值