前提:需要前后端一起配合完成;
动态路由的控制
在登录接口,后端返回当前用户拥有的权限;
拿到 之后 我们利用这个实现动态路由;我们把他存放到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();
}
}