我正在参加 「掘金日新计划 · 4 月更文挑战」,今天要讲的是路由权限以及指令权限(按钮级别的权限)的实现原理。
路由权限
在Vue admin manage的后台管理系统中,通常需要实现动态路由,以便根据用户权限动态生成菜单和路由。以下是实现动态路由的一般步骤
在路由配置中定义动态路由
在Vue的路由配置中,可以定义动态路由,例如:
const routes = [
{
path: '/',
name: 'Dashboard',
component: Dashboard,
meta: { requiresAuth: true }
},
{
path: '/users',
name: 'Users',
component: Users,
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: '/products',
name: 'Products',
component: Products,
meta: { requiresAuth: true }
},
// ...
]
上面的代码中,每个路由都有一个meta属性,用于存储路由的元数据。其中,requiresAuth表示该路由需要用户登录后才能访问,requiresAdmin表示该路由需要管理员权限才能访问。
在路由守卫中根据权限动态生成路由
在Vue的路由导航守卫中,可以根据用户权限动态生成路由和菜单。例如:
router.beforeEach((to, from, next) => {
// 判断用户是否已经登录
const isAuthenticated = store.getters.isAuthenticated;
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!isAuthenticated) {
// 如果用户未登录,则跳转到登录页
next({ name: 'Login' });
} else {
// 根据用户权限动态生成路由
const userPermissions = store.getters.userPermissions;
const routes = generateRoutes(userPermissions);
router.addRoutes(routes);
next();
}
} else {
next('/403') // 如果权限不足,则跳转到 403 页面
}
})
function generateRoutes(userPermissions) {
const routes = [];
// 根据用户权限动态生成路由
if (userPermissions.indexOf('admin') !== -1) {
routes.push({
path: '/admin',
name: 'Admin',
component: Admin,
meta: { requiresAuth: true, requiresAdmin: true }
});
}
// ...
return routes;
}
上面的代码中,beforeEach路由守卫会在每次路由跳转前执行。如果to路由需要用户登录才能访问,则判断用户是否已经登录。如果已经登录,则根据用户权限动态生成路由,并通过router.addRoutes()方法动态添加路由。最后调用next()方法,继续路由跳转。
admin 超管权限 可以访问所有路由,editor编辑权限 onlyRead 只读权限
可实现具体效果图如下:
在菜单组件中根据路由生成菜单
在Vue的菜单组件中,可以根据路由动态生成菜单。例如:
<template>
<ul>
<li v-for="route in routes" :key="route.name">
<router-link :to="route.path">{{ route.name }}</router-link>
<ul v-if="route.children">
<menu :routes="route.children"></menu>
</ul>
</li>
</ul>
</template>
<script>
export default {
name: 'Menu',
props: {
routes: {
type: Array,
required: true
}
},
computed: {
filteredRoutes() {
return this.routes.filter(route => {
return route.meta && route.meta.requiresAuth;
})
}
}
}
</script>
上面的代码中,Menu组件根据传入的routes属性动态生成菜单。如果路由有子路由,则递归调用Menu组件生成子菜单。
通过上述步骤,就可以实现基于动态路由的后台管理系统了。
自定义指令来实现权限控制
在Vue中,可以通过自定义指令来实现权限控制。又被称为按钮级别的权限控制实现。具体步骤如下:
定义自定义指令
可以使用Vue.directive()方法来定义自定义指令。例如:
Vue.directive('permission', {
inserted: function (el, binding) {
// 根据用户权限来决定是否显示元素
if (!checkPermission(binding.value)) {
el.parentNode.removeChild(el);
}
}
})
上面的代码定义了一个名为permission的指令,实际可以根据需求命名,如你需要一个仅可以编辑的可以命名为 check-editor 等。具体情况具体分析,这里要说明一下,它会在元素插入到DOM中时执行inserted函数。在该函数中,根据用户权限来判断是否显示元素。
在模板中使用自定义指令
在模板中使用自定义指令时,只需要将指令名作为元素的属性即可。例如:
<button v-permission="'edit'">编辑</button>
上面的代码中,v-permission指令的值为'edit',表示只有拥有编辑权限的用户才能看到该按钮。
checkPermission函数的实现
checkPermission函数主要是用来判断当前用户是否拥有某项权限的函数。它可以从服务端获取用户信息,亦或者从本地存储中读取用户权限信息。例如:
function checkPermission(permission) {
const roles = store.getters && store.getters.roles
if (roles.indexOf(permission) !== -1) {
return true;
} else {
return false;
}
}
上面的代码中,checkPermission函数从token中读取用户权限信息,判断是否拥有指定权限。当然也可以使用本地存储来读取实现用户权限信息
综上所述步骤,就可以实现基于自定义指令的权限控制了。
可实现具体效果图如下: