核心问题在于await阻塞Vue响应式更新与DOM渲染,导致骨架屏无法及时显示;应将骨架屏设为路由切换默认起点,用Suspense包裹异步组件并配合fallback插槽,守卫仅做同步校验,数据获取移至组件内,辅以超时降级与错误边界兜底。

核心问题不在“拦截器”本身,而在于 await 阻塞了 Vue 的响应式更新与 DOM 渲染流程。骨架屏(Skeleton)本应作为占位 UI 立即呈现,但如果路由守卫(如 beforeEach)里执行了未加控制的 await,整个导航过程就会卡住——骨架屏组件根本没机会被挂载或渲染。
确保骨架屏在路由守卫前就已可见
骨架屏必须脱离“等待数据完成才显示”的逻辑,它应是路由切换的默认视觉起点:
- 在
<router-view>外层包裹静态骨架结构,不依赖任何异步状态 - 使用
<Suspense>(Vue 3)包裹异步组件,配合fallback插槽直接写骨架屏,而非靠 JS 控制显隐 - 避免在守卫中调用需长时间 resolve 的 API;把数据获取移到组件内、配合
onMounted+loading状态管理,让骨架屏由组件自身控制
拆分守卫职责:校验与加载分离
路由守卫应只做轻量同步判断(如权限检查、token 有效性),重逻辑后移:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 权限校验类操作用同步方式(如读取 localStorage、验证 JWT payload)
- 用户信息、菜单配置等需请求的数据,改由目标组件的
setup或onBeforeRouteEnter(组合式 API 中可用useRoute+onMounted)触发,不阻塞导航 - 若必须在守卫中请求,务必设置超时(
AbortSignal)并 fallback 到默认布局,防止无限等待
用 Suspense + 异步组件替代守卫级 await
这是最符合 Vue 3 设计意图的解法:
- 将页面组件定义为异步组件:
defineAsyncComponent(() => import('./Home.vue')) - 在父级模板中用
<Suspense>包裹<router-view>,其fallback内直接写骨架屏结构 - 组件内部用
async setup()加载数据,此时骨架屏已渲染,且Suspense会自动等待组件 resolve 并平滑过渡
兜底策略:超时降级与错误边界
即使做了上述优化,网络异常或服务不可用仍可能导致骨架屏长期停留:
- 在异步组件或组件 setup 中,对 fetch 设置明确 timeout(如 8s),超时后显示友好提示页,而非无限骨架
- 配合
<ErrorBoundary>(或 Vue 3 的errorCaptured钩子)捕获渲染异常,防止白屏 - 利用
keep-alive缓存已成功加载的页面,减少重复骨架屏展示频率


















