mirror of
https://github.com/un-pany/v3-admin-vite.git
synced 2025-04-20 19:09:21 +08:00
refactor: 简化路由守卫逻辑
This commit is contained in:
parent
160f389c60
commit
b92a1a24fc
@ -22,19 +22,13 @@ router.beforeEach(async (to, _from, next) => {
|
||||
// 判断该用户是否已经登录
|
||||
if (!token) {
|
||||
// 如果在免登录的白名单中,则直接进入
|
||||
if (isWhiteList(to)) {
|
||||
next()
|
||||
} else {
|
||||
// 其他没有访问权限的页面将被重定向到登录页面
|
||||
NProgress.done()
|
||||
next("/login")
|
||||
}
|
||||
return
|
||||
if (isWhiteList(to)) return next()
|
||||
// 其他没有访问权限的页面将被重定向到登录页面
|
||||
return next("/login")
|
||||
}
|
||||
|
||||
// 如果已经登录,并准备进入 Login 页面,则重定向到主页
|
||||
if (to.path === "/login") {
|
||||
NProgress.done()
|
||||
return next({ path: "/" })
|
||||
}
|
||||
|
||||
@ -44,16 +38,11 @@ router.beforeEach(async (to, _from, next) => {
|
||||
// 否则要重新获取权限角色
|
||||
try {
|
||||
await userStore.getInfo()
|
||||
if (routeSettings.async) {
|
||||
// 注意:角色必须是一个数组! 例如: ['admin'] 或 ['developer', 'editor']
|
||||
const roles = userStore.roles
|
||||
// 根据角色生成可访问的 Routes(可访问路由 = 常驻路由 + 有访问权限的动态路由)
|
||||
permissionStore.setRoutes(roles)
|
||||
} else {
|
||||
// 没有开启动态路由功能,则启用默认角色来生成
|
||||
permissionStore.setRoutes(routeSettings.defaultRoles)
|
||||
}
|
||||
// 将'有访问权限的动态路由' 添加到 Router 中
|
||||
// 注意:角色必须是一个数组! 例如: ["admin"] 或 ["developer", "editor"]
|
||||
const roles = userStore.roles
|
||||
// 生成可访问的 Routes
|
||||
routeSettings.async ? permissionStore.setRoutes(roles) : permissionStore.setAllRoutes()
|
||||
// 将 "有访问权限的动态路由" 添加到 Router 中
|
||||
permissionStore.dynamicRoutes.forEach((route) => router.addRoute(route))
|
||||
// 确保添加路由已完成
|
||||
// 设置 replace: true, 因此导航将不会留下历史记录
|
||||
@ -62,7 +51,6 @@ router.beforeEach(async (to, _from, next) => {
|
||||
// 过程中发生任何错误,都直接重置 Token,并重定向到登录页面
|
||||
userStore.resetToken()
|
||||
ElMessage.error(err.message || "路由守卫过程发生错误")
|
||||
NProgress.done()
|
||||
next("/login")
|
||||
}
|
||||
})
|
||||
|
@ -29,13 +29,23 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
const routes = ref<RouteRecordRaw[]>([])
|
||||
const dynamicRoutes = ref<RouteRecordRaw[]>([])
|
||||
|
||||
/** 根据角色生成可访问的 Routes(可访问路由 = 常驻路由 + 有访问权限的动态路由) */
|
||||
const setRoutes = (roles: string[]) => {
|
||||
const accessedRoutes = routeSettings.async ? filterAsyncRoutes(asyncRoutes, roles) : asyncRoutes
|
||||
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
|
||||
_set(accessedRoutes)
|
||||
}
|
||||
|
||||
/** 所有路由 = 所有常驻路由 + 所有动态路由 */
|
||||
const setAllRoutes = () => {
|
||||
_set(asyncRoutes)
|
||||
}
|
||||
|
||||
const _set = (accessedRoutes: RouteRecordRaw[]) => {
|
||||
routes.value = constantRoutes.concat(accessedRoutes)
|
||||
dynamicRoutes.value = routeSettings.thirdLevelRouteCache ? flatMultiLevelRoutes(accessedRoutes) : accessedRoutes
|
||||
}
|
||||
|
||||
return { routes, dynamicRoutes, setRoutes }
|
||||
return { routes, dynamicRoutes, setRoutes, setAllRoutes }
|
||||
})
|
||||
|
||||
/** 在 setup 外使用 */
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { ref } from "vue"
|
||||
import store from "@/store"
|
||||
import { defineStore } from "pinia"
|
||||
import { usePermissionStore } from "./permission"
|
||||
import { useTagsViewStore } from "./tags-view"
|
||||
import { useSettingsStore } from "./settings"
|
||||
import { getToken, removeToken, setToken } from "@/utils/cache/cookies"
|
||||
import router, { resetRouter } from "@/router"
|
||||
import { resetRouter } from "@/router"
|
||||
import { loginApi, getUserInfoApi } from "@/api/login"
|
||||
import { type LoginRequestData } from "@/api/login/types/login"
|
||||
import { type RouteRecordRaw } from "vue-router"
|
||||
import routeSettings from "@/config/route"
|
||||
|
||||
export const useUserStore = defineStore("user", () => {
|
||||
@ -16,7 +14,6 @@ export const useUserStore = defineStore("user", () => {
|
||||
const roles = ref<string[]>([])
|
||||
const username = ref<string>("")
|
||||
|
||||
const permissionStore = usePermissionStore()
|
||||
const tagsViewStore = useTagsViewStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
@ -33,18 +30,13 @@ export const useUserStore = defineStore("user", () => {
|
||||
// 验证返回的 roles 是否为一个非空数组,否则塞入一个没有任何作用的默认角色,防止路由守卫逻辑进入无限循环
|
||||
roles.value = data.roles?.length > 0 ? data.roles : routeSettings.defaultRoles
|
||||
}
|
||||
/** 切换角色 */
|
||||
/** 模拟角色变化 */
|
||||
const changeRoles = async (role: string) => {
|
||||
const newToken = "token-" + role
|
||||
token.value = newToken
|
||||
setToken(newToken)
|
||||
await getInfo()
|
||||
permissionStore.setRoutes(roles.value)
|
||||
resetRouter()
|
||||
permissionStore.dynamicRoutes.forEach((item: RouteRecordRaw) => {
|
||||
router.addRoute(item)
|
||||
})
|
||||
_resetTagsView()
|
||||
// 用刷新页面代替重新登陆
|
||||
window.location.reload()
|
||||
}
|
||||
/** 登出 */
|
||||
const logout = () => {
|
||||
|
@ -2,16 +2,10 @@
|
||||
import { ref, watch } from "vue"
|
||||
import { useUserStore } from "@/store/modules/user"
|
||||
|
||||
/** Vue 3.3+ defineEmits 语法 */
|
||||
const emit = defineEmits<{
|
||||
change: []
|
||||
}>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const switchRoles = ref(userStore.roles[0])
|
||||
watch(switchRoles, async (value) => {
|
||||
await userStore.changeRoles(value)
|
||||
emit("change")
|
||||
watch(switchRoles, (value) => {
|
||||
userStore.changeRoles(value)
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -19,7 +13,7 @@ watch(switchRoles, async (value) => {
|
||||
<div>
|
||||
<div>你的权限:{{ userStore.roles }}</div>
|
||||
<div class="switch-roles">
|
||||
<span>切换权限:</span>
|
||||
<span>切换权限(模拟权限变化后重新登陆):</span>
|
||||
<el-radio-group v-model="switchRoles">
|
||||
<el-radio-button label="editor" />
|
||||
<el-radio-button label="admin" />
|
||||
|
@ -1,20 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue"
|
||||
import { checkPermission } from "@/utils/permission" // checkPermission 权限判断函数
|
||||
import { checkPermission } from "@/utils/permission"
|
||||
import SwitchRoles from "./components/SwitchRoles.vue"
|
||||
|
||||
/** key 是为了能每次切换权限的时候重新初始化指令 */
|
||||
const key = ref(1)
|
||||
const handleRolesChange = () => {
|
||||
key.value++
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<SwitchRoles @change="handleRolesChange" />
|
||||
<SwitchRoles />
|
||||
<!-- v-permission 示例 -->
|
||||
<div :key="key" class="margin-top-30">
|
||||
<div class="margin-top-30">
|
||||
<div>
|
||||
<el-tag v-permission="['admin']" type="success" size="large" effect="plain">
|
||||
这里采用了 v-permission="['admin']" 所以只有 admin 可以看见这句话
|
||||
@ -32,7 +25,7 @@ const handleRolesChange = () => {
|
||||
</div>
|
||||
</div>
|
||||
<!-- checkPermission 示例 -->
|
||||
<div :key="`checkPermission${key}`" class="margin-top-30">
|
||||
<div class="margin-top-30">
|
||||
<el-tag type="warning" size="large">
|
||||
例如 Element Plus 的 el-tab-pane 或 el-table-column 以及其它动态渲染 Dom 的场景不适合使用
|
||||
v-permission,这种情况下你可以通过 v-if 和 checkPermission 来实现:
|
||||
|
Loading…
x
Reference in New Issue
Block a user