写在前面
在Vue中,Router是一个官方提供的用于处理应用程序路由的插件。它允许我们创建单页应用程序(SPA),其中不同的页面和组件可以通过URL进行导航和展示。使我们可以轻松地创SPA,并实现可复用和可组合的组件导航。
在实际开发中,我们常常会碰到不同角色进入系统所展示的路由,和页面是不同的。那么我们该如何实现router的权限控制呢?
1.pinia配置
我们使用pinia来存储用户信息及权限,在登录时进行调用设置,同时也是router权限判断的依据
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const userPermissionsStore = defineStore('userPermissions', () => {
const roles = ref('') // 角色
const permissions = ref([]) // 权限
const isLogin = ref(false) //登录状态
// 设置状态(传入的权限信息赋值给该状态)
const setUserPermissions = (params) => {
userPermissions.value = params
}
return {
isLogin,
userPermissions,
roles,
setUserPermissions,
}
})
2.router配置
在router配置中我们对需要权限限制的路由进行路由权限和受访问权限角色的设置,同时配置路由守卫用于判断跳转路由前是否有权限
import { createWebHistory, createRouter } from 'vue-router'
import { userPermissionsStore } from '../store'
import Layout from '../View/Layout.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: Layout,
redirect: '/home',
children: [
{
path: '/home',
component: () => import('../View/home.vue'),
},
{
path: '/admin',
component: () => import('../View/adminPage.vue'),
meta: {
requireAuth: true, // 需要路由权限
roles: ['admin'], // 受访问权限的角色
},
},
{
path: '/superAdmin',
component: () => import('../View/superAdminPage.vue'),
meta: {
requireAuth: true, // 需要路由权限
roles: ['superAdmin'], // 受访问权限的角色
},
},
{
path: '/user',
component: () => import('../View/user.vue'),
},
],
},
{
path: '/login',
component: () => import('../View/login.vue'),
},
{
path: '/404',
component: () => import('../View/404.vue'),
},
],
})
// 添加路由前置守卫
router.beforeEach((to, from, next) => {
const store = userPermissionsStore()
// 判断该路由是否需要登录权限
if (to.meta.requireAuth) {
// 校验用户是否已经登录
if (store.isLogin) {
// 判断当前用户是否有访问该路由的权限
if (to.meta.roles.includes(store.roles)) {
// 用户有访问权限,直接进入页面
next()
} else {
// 用户无访问权限,跳转到其他页面
next('/404')
}
} else {
// 如果用户未登录,则跳转到登录页面
next('/login')
}
}
})
export default router
3.RouterLink配置
我们可以根据当前角色和权限来控制RouterLink的显隐
<template>
<ul class="nav">
<RouterLink to="/">首页</RouterLink>
<RouterLink to="/superAdmin" v-if="hasPermission('superAdmin')" >超级管理员显示</RouterLink>
<RouterLink to="/admin" v-if="hasPermission('admin')">管理员显示</RouterLink>
<RouterLink to="/user">用户显示</RouterLink>
<li>
<button @click="quiteLogin">退出登录</button>
</li>
</ul>
<div class="container">
<RouterView />
</div>
</template>
<script setup>
import { RouterLink, useRouter } from 'vue-router'
import { userPermissionsStore } from '../store'
import { onMounted } from 'vue'
const store = userPermissionsStore()
const router = useRouter()
// 判断当前的角色是否可访问 来控制跳转链接的显隐
const hasPermission = (i) => {
return store.permissions.includes(i)
}
// 退出登录时将Piain存储的值清空
const quiteLogin = () => {
router.push('/login')
store.permissions= []
store.isLogin = false
}
// 判断当前是否登录
onMounted(() => {
if (!isLogin.value) {
router.push('/login')
}
})
</script>
4.登录页配置
在登陆时来调用pinia来存储相关数据
<template>
<div>
<select v-model="name">
<option value="superAdmin">超级管理员</option>
<option value="admin">管理员</option>
<option value="user">用户</option>
</select>
<button @click="login">登录</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { userPermissionsStore } from '../store'
import { useRouter } from 'vue-router'
const userPermissions = userPermissionsStore()
const name = ref('')
const router = useRouter()
const login = () => {
userPermissions.isLogin = true
userPermissions.roles = name.value
userPermissions.userPermissions.push(name.value)
router.push('/')
}
</script>