大多数开源项目都是在beforeEach里判断token 预请求数据等等,代码那是相当复杂,因为接口请求,状态持久化必须全要在一起做,不然容易状态不同步出bug,但是全写在一起,东西太多,也容易出错了
如果把登录页和内容页分成两个vue实例,做成多页应用的样子,登录成功先获取前置数据,再根据数据生成菜单,最后new App 以后再跳转首页,而且这些前置数据天然就有,在整个代码文件里直接就用使用,状态持久化也是小case
动态权限常见的需求就是刷新页面,更新权限。本方案也是支持的。 动态权限有个特别需要注意的点是,如果走到请求前置接口的if条件里,说明from是 404来的, addRoute之后需要重定向到其他页面, 而这个重定向经常失效(不知道为啥, 可能我使用不对, 总之坑不少)
不管vue还是react应该都可以这样搞,我看很多老外开源的项目也是这样,比如 ui-kittens
整个权限架构,核心就以下几行代码而已
架构
//bootstrap.ts
export const bootstrapApp = async ()=>{
await fetchData()
new Vue() // 内容页vue实例 内容页router
return {router}
}
// main.js
import {bootstrapApp} from './bootstrap.ts'
if(location.path === 'login'){
new Vue({template:'LoginComponent'}).mount('#app') // 登录页vue实例 注册登录等routes路由表
// 登录成功以后,调用 bootstrapApp().then(()=>location.href='/')
else
if(localStorage 里有 token)
bootstrapApp().then(({router})=>router.push(location.pathname) )
else
location.href='/login'
提一点,用了beforeEach单页应用架构。希望把预请求当app.vue里达到简化代码的目的,是不行的。因为 预请求接口涉及到请求和pinia存储。貌似ap.vue执行时 pinia还没初始化好, 总之没有啥好办法简化beforeach
import { initUser } from './user';
initUser().then(()=> {
let router = createBrowserRouter(routes);
let root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<RouterProvider router={router} />);
});