@author 郭瑞峰 @createTime 2023/06/18 @updateTime 2023/06/20
前言
好久没写文章了,还是写一些解决方案吧,不然会很尴尬
ㄟ( ▔, ▔ )ㄏ
啥是路由权限
先说大白话哈,路由权限就是不能去的地方坚决不能去,能去的地方马上放行
解决方案
目前我的解决方案为两种:
- 全部加载后再判断
- 后端提供“名单”后重新加载
全部加载后再判断
顾名思义,所有路由加载进来,对每一个路由进行校验
- vue-router 方案
// vue-router 配置
import { createRouter,createWebHashHistory, type RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('../components/HelloWorld.vue'),
meta: {
isAuth: false
}
},
{
path: '/aaa',
component: () => import('../components/aaa.vue'),
meta: {
isAuth: true
}
}
]
const router = createRouter({
routes: routes,
history: createWebHashHistory()
})
router.beforeEach((to, from, next) => {
if (!to.meta.isAuth) {
// 无需认证,直接放行
next()
} else {
// 认证
if (......认证通过) { next() }
// 认证失败
next(from)
}
})
export default router
- react-router 暂时不建议这样操作
后端提供“名单”后重新加载
后端请求完数据后,前端渲染
- vue + pinia + vue-router 的解决方案
import { defineStore } from 'pinia'
import { useRouter } from 'vue-router'
const indexStore = defineStore('index', () => {
const getRoutes = (): void => {
fetch('xxxxxxx')
.then(response => response.json())
.then(({ data }: any) => {
// 这里添加后端返还的路由
const $router = useRouter()
data.forEach(({parentName, route}) => {
// 后端可以提供名单,也可以只提供 string[] ,让前端自己匹配名单
$router.addRoute(parentName, route)
});
})
.catch(() => {
......
})
}
return {
getRoutes
}
})
export default indexStore
- react + react-router
// router.tsx
import React from 'react'
import { type RouteObject } from 'react-router-dom'
import MyLayout from '../components/organisms/MyLayout'
import Aaa from '../pages/app/aaa'
import A2 from '../pages/app/a2'
import { nestComponents } from '../utils/routesUtils'
const routeDict: Record<string, RouteObject> = {
app: { path: '/app', element: (<MyLayout/>) },
appTest: { path: '/app/test', element: (nestComponents([MyLayout, Test])) },
appAaa: { path: '/app/aaa', element: (nestComponents([MyLayout, Aaa])) },
appA2: { path: '/app/a2', element: (nestComponents([MyLayout, A2])) }
}
const getRoute = (dict: string[]): RouteObject[] => {
if (dict.length === 0) { return [] }
// 这里应该写个默认值,防止后端提供字符串没有匹配上
return dict.map(item => routeDict[item])
}
import React, { useState } from 'react'
import { BrowserRouter, Routes, Route } from 'react-router'
import getRoute from './router.tsx'
const App: React.FC = () => {
const [routes, getRoutes] = useState<string[]>([])
// 获取路由
........
return (
<BrowserRouter>
<Routes>
{
// 根据字典加载路由
getRoute().map(item => (
<Route key={item.path} path={item.path} element={item.element} />
))
}
</Routes>
</BrowserRouter>
)
}
App.displayName = 'App'
export default App