Skip to content

Vue重构案例导航图

前面的案例文档和统一框架,已经覆盖了不少常见的 Vue 重构场景。接下来最有用的补充,不是再加一篇零散案例,而是做一份“按问题找案例”的导航图。

这篇文档的作用很简单:当你遇到某类 Vue 项目问题时,可以先来这里定位,再跳到对应案例和总框架里看细节。

使用顺序建议

推荐按下面这个顺序使用整套文档:

  • 先读 Vue练习项目重构统一框架,建立总方法论
  • 再按本文的问题分类,找到最接近的案例
  • 最后回到对应案例文档,看具体拆分方式和 composable 设计

如果你已经知道自己卡在哪种问题上,可以直接从下面的分类导航开始。

一、按项目类型找案例

页面型项目

这类项目的典型特征是:页面里同时存在请求、状态、交互和展示,容器组件容易越写越胖。

优先看这几篇:

适合解决的问题:

  • 页面容器过重
  • 多个 UI 区块都堆在一个页面里
  • 列表、表单、筛选、统计、弹窗混在一起
  • 请求、副作用和模板耦合严重

基础组件型项目

这类项目的典型特征是:你不是在写某个页面,而是在写可复用组件,问题更多来自协议设计、组件通信和扩展能力。

优先看这几篇:

适合解决的问题:

  • 基础组件越写越像业务组件
  • 组件扩展能力越来越乱
  • 内部通信依赖事件名或组件名
  • 外部消费 API 不稳定

运行时边界型项目

这类项目的典型特征是:问题不只发生在组件内部,而发生在服务端与客户端之间的数据准备、状态注入和接管边界上。

优先看这几篇:

适合解决的问题:

  • 服务端与客户端数据流不一致
  • 首屏重复请求
  • 初始状态恢复不稳定
  • 页面组件知道太多运行时细节

框架场景型项目

这类项目的典型特征是:问题已经不只是 Vue 基础能力,而是框架约定、目录结构、数据获取 API 和运行时边界一起参与设计。

优先看这几篇:

适合解决的问题:

  • 页面首屏数据应该怎么拿
  • SSR 与 hydration 边界如何控制
  • composable 与页面如何分层
  • 渲染模式应该如何选择

状态管理型项目

这类项目的典型特征是:问题的核心不在页面模板,而在 store 边界、业务域划分、全局状态归属和迁移策略。

优先看这几篇:

适合解决的问题:

  • 哪些状态该进入全局 store
  • store 是否应该按业务域拆分
  • Vuex 到 Pinia 如何渐进迁移
  • action 和副作用如何分层

路由与布局型项目

这类项目的典型特征是:问题已经不只是页面本身,而是根应用壳层、布局切换、路由出口和页面缓存会在同一层相互影响。

优先看这几篇:

适合解决的问题:

  • 根应用和页面层如何切边界
  • 布局切换如何走显式协议
  • 页面缓存如何设计 include / exclude 策略
  • 页面激活与失活如何区别处理

容错与降级型项目

这类项目的典型特征是:问题已经不只是页面数据和交互,而是组件报错、浏览器环境限制和 fallback 恢复路径会一起影响页面可用性。

优先看这几篇:

适合解决的问题:

  • 浏览器专属组件如何安全地进入页面
  • 局部错误如何隔离,不影响页面主体
  • fallback 和恢复动作如何统一设计
  • 页面级错误与局部错误如何分层

异步加载型项目

这类项目的典型特征是:问题已经不只是组件能不能拆包,而是 loading、error、timeout、客户端延迟挂载和首屏可用性会一起影响页面体验。

优先看这几篇:

适合解决的问题:

  • 哪些模块值得异步化
  • loading / error / timeout 如何统一处理
  • 客户端专属大组件如何延迟挂载
  • fallback 和重试路径如何设计

Nuxt运行时边界型项目

这类项目的典型特征是:问题已经不只是页面与数据,而是请求级处理、路由准入、插件注入和页面消费层会在同一个运行时体系里互相影响。

优先看这几篇:

适合解决的问题:

  • 请求级、导航级、应用级、页面级职责如何切分
  • Nitro 中间件与路由中间件如何分层
  • 插件如何只做能力注入,不做业务编排
  • 页面如何只消费能力,不理解底层运行时顺序

Nuxt执行时机型项目

这类项目的典型特征是:问题已经不只是逻辑放在哪个目录,而是同一段逻辑在服务启动、单次请求、SSR 渲染、客户端挂载和后续导航中的执行时机越来越混乱。

优先看这几篇:

适合解决的问题:

  • 启动级、请求级、导航级、渲染级、客户端交互级逻辑如何分段
  • 浏览器 API、订阅和计时器如何避免混入 SSR 链路
  • 首屏数据准备和客户端副作用如何拆开
  • 清理逻辑如何和副作用本身绑定

Nuxt依赖边界型项目

这类项目的典型特征是:问题已经不只是页面代码长不长,而是自动导入、公用 composable 和目录暴露面让依赖关系越来越隐式。

优先看这几篇:

适合解决的问题:

  • 默认自动导入、应用公共入口和 feature 内部实现如何分层
  • imports.dirs 应该如何筛选,而不是一路膨胀
  • server-only、client-only 和双端共享能力如何分开组织
  • 页面如何保持轻量,同时不失去依赖可读性

Nuxt页面编排型项目

这类项目的典型特征是:问题已经不只是 composable 有没有抽出来,而是页面入口、页面业务 composable、局部步骤和 store 之间的编排边界越来越混乱。

优先看这几篇:

适合解决的问题:

  • 页面入口层和页面业务 composable 层如何分层
  • feature 步骤 composable 和 store 如何划清归属
  • 页面级数据、SEO、埋点和 query 同步如何围绕同一份契约组织
  • 页面如何保持足够轻,但不丢失业务语义

Nuxt模块组织型项目

这类项目的典型特征是:问题已经不只是页面和 composable 怎么拆,而是同一条业务链路被技术目录切碎,feature 私有实现和公共层边界越来越模糊。

优先看这几篇:

适合解决的问题:

  • 业务主线如何成为第一组织单位
  • feature 私有实现和应用公共层如何划清边界
  • 页面、store 和服务端接口如何围绕同一业务模块对齐
  • 目录结构如何帮助快速追踪一条业务链路

Nuxt公共层治理型项目

这类项目的典型特征是:问题已经不只是 feature 怎么拆,而是应用公共层、自动导入入口和共享能力越来越膨胀,伪复用能力越来越多。

优先看这几篇:

适合解决的问题:

  • 哪些能力值得进入应用公共层
  • 共享协议和业务桥接层如何区分
  • 自动导入与公共暴露面如何控制
  • 伪复用能力如何回收回 feature 内部

Nuxt接口边界型项目

这类项目的典型特征是:问题已经不只是页面怎么拿数据,而是 server/api、请求上下文、下游服务和页面契约越来越混在一起。

优先看这几篇:

适合解决的问题:

  • 页面消费层、BFF 接口层、服务组装层如何分层
  • server/api 如何表达页面级契约,而不是透传底层结构
  • 请求上下文准备和接口级业务组装如何拆开
  • 页面数据获取语义和服务端输出语义如何协同

Nuxt响应策略型项目

这类项目的典型特征是:问题已经不只是页面怎么拿数据,而是页面价值、渲染模式、缓存策略和响应方式必须一起设计。

优先看这几篇:

适合解决的问题:

  • 页面价值如何映射到渲染模式
  • routeRules 如何表达页面级响应策略
  • swr / isr / prerender 如何与内容更新节奏对齐
  • 页面数据流与响应缓存流如何协同

认证与权限型项目

这类项目的典型特征是:问题已经不只是一个登录页,而是登录态、请求拦截、路由准入和页面回跳会在多个层次同时发生。

优先看这几篇:

适合解决的问题:

  • 登录页和会话系统如何分离
  • 请求层如何从 UI 和 store 细节中解耦
  • 路由守卫如何显式表达准入协议
  • 登录后回跳和失效退出如何统一处理

复杂交互型项目

这类项目的典型特征是:问题已经不只是数据和组件,而是一次操作会带动多个区域、多个浮层和多个反馈动画共同变化。

优先看这几篇:

适合解决的问题:

  • 动画和业务状态如何分离
  • 多个浮层如何统一管理
  • 动画请求如何建立统一入口
  • 复杂交互页面如何避免容器过重

二、按复杂度中心找案例

如果你还不确定项目属于哪类,可以反过来,从“复杂度中心”来找。

1. 状态中心不清晰

表现通常是:多个组件都在改同一份数据,或者页面里同时存在原始状态、派生状态和副作用。

优先看:

对应的重构方向通常是:

  • 把核心业务状态收口到 useXxx
  • 把派生状态移到 computed
  • 把页面层改成状态装配器

2. 组件职责过重

表现通常是:一个组件既拿数据、又算派生状态、又处理副作用、还负责大片模板。

优先看:

对应的重构方向通常是:

  • 页面层只保留页面职责
  • 递归节点只做展示和事件入口
  • 展示组件统一收窄成 props / emits

3. 深层通信过于隐式

表现通常是:依赖事件总线、组件名查找、深层 watch、副作用式同步。

优先看:

对应的重构方向通常是:

  • provide/inject 替代层级查找
  • 用显式上下文替代隐式事件
  • 用 composable 替代分散的通信约定

4. 扩展协议不稳定

表现通常是:组件可以扩展,但方式越来越多,外部不清楚应该优先用哪种能力。

优先看:

对应的重构方向通常是:

  • 先定义协议类型
  • 再实现桥接层和消费层
  • 把扩展能力控制在少数主路径里

5. 页面交互链路太长

表现通常是:一个操作会牵动多个区域,比如点餐页里商品、购物车、详情和动画会互相影响,或者社区页里登录、发帖、点赞、回复相互耦合。

优先看:

对应的重构方向通常是:

  • 把长链路拆成多个状态中心
  • 把动画、弹窗、列表、会话拆成并列能力模块
  • 让页面只负责装配这些能力

6. SSR 与水合边界不稳定

表现通常是:服务端和客户端都在准备数据,但边界不清,导致二次请求、状态不一致或水合问题。

优先看:

对应的重构方向通常是:

  • 把服务端预取和客户端补预取收口成统一协议
  • 把请求级状态和水合恢复边界稳定下来
  • 让页面组件只声明数据依赖

7. Nuxt 页面数据流与渲染边界混乱

表现通常是:页面能跑,但首屏数据、客户端状态、hydration 和渲染模式混在一起。

优先看:

对应的重构方向通常是:

  • 先判断页面属于哪种渲染对象
  • 先分离首屏数据和局部交互状态
  • 先控制 hydration 边界,再写客户端逻辑

8. 全局状态边界越来越模糊

表现通常是:store 越来越大,什么都往里放,action 越来越像全局副作用集散地。

优先看:

对应的重构方向通常是:

  • 先判断哪些状态应全局化
  • 先按业务域拆状态中心
  • 先分离副作用,再迁移 Pinia

9. 认证、请求与路由权限互相牵连

表现通常是:登录成功后跳转、请求头注入、401 失效处理和页面准入判断散在不同文件里。

优先看:

对应的重构方向通常是:

  • 先把会话状态收口
  • 先让请求层只处理协议适配
  • 先让路由准入变成显式 meta 协议

10. 路由切换、缓存和布局职责缠在一起

表现通常是:根组件越来越重,router-view 同时承担布局、缓存和页面出口,页面切回来状态又不稳定。

优先看:

对应的重构方向通常是:

  • 先拆应用壳层和页面层
  • 先把缓存策略收口成显式协议
  • 先区分 mountedactivated 语义

11. 组件报错、客户端依赖与降级内容混在一起

表现通常是:某个局部模块一失败就影响整页,可客户端模块、业务错误和 fallback 提示又没有清晰分层。

优先看:

对应的重构方向通常是:

  • 先分离运行环境边界和业务错误边界
  • 先定义局部错误隔离与恢复动作
  • 先让 fallback 成为显式设计的一部分

12. loading、error、timeout 和延迟模块越来越碎

表现通常是:页面里到处都是异步模块,但占位内容、失败态和恢复动作没有统一结构。

优先看:

对应的重构方向通常是:

  • 先判断哪些模块值得异步化
  • 先把 loading / error / timeout 收口成统一边界
  • 先把占位和重试动作设计出来

13. 中间件、插件和页面逻辑越写越缠

表现通常是:请求级逻辑、导航级判断、应用注入和页面消费层彼此越写越重叠。

优先看:

对应的重构方向通常是:

  • 先拆请求级、导航级、应用级、页面级职责
  • 先让插件回到能力注入边界
  • 先让页面只消费稳定能力入口

14. routeRules、缓存和页面价值越来越脱节

表现通常是:页面已经分化成内容页、后台页、交互页,但渲染模式和缓存策略仍然没有形成统一规则。

优先看:

对应的重构方向通常是:

  • 先按页面价值分类
  • 先让 routeRules 成为页面级策略表达
  • 先让数据流和缓存流围绕同一套语义协同

15. 生命周期钩子、副作用和清理时机越来越混乱

表现通常是:同一段逻辑有时在服务端执行,有时在客户端执行,还有一部分副作用没有明确清理点。

优先看:

对应的重构方向通常是:

  • 先拆启动级、请求级、导航级、渲染级、客户端交互级时机
  • 先把数据准备和副作用触发分开
  • 先让清理逻辑和副作用写在同一层

16. 自动导入越来越多,但依赖关系越来越看不清

表现通常是:页面 import 越来越少,但公共入口、局部实现和环境前提都一起变得模糊。

优先看:

对应的重构方向通常是:

  • 先拆默认框架能力、应用公共入口和 feature 内部实现
  • 先收缩 imports.dirs 的暴露面
  • 先让页面只消费稳定入口,内部实现回到显式导入

17. 页面里的 composable 越来越多,但编排边界越来越说不清

表现通常是:页面文件虽然不算长,但 setup() 里同时装配数据、SEO、query 同步、埋点和多个业务 composable,复杂度只是换了位置。

优先看:

对应的重构方向通常是:

  • 先拆页面入口层、页面业务 composable 层和 feature 步骤层
  • 先让页面只消费少量稳定入口
  • 先把页面局部状态从 store 回收回来

18. feature 目录建了,但业务链路还是很难追

表现通常是:虽然已经有 features/,但页面、store、组件和服务端逻辑依然散在全局技术目录里,模块边界并没有真正稳定下来。

优先看:

对应的重构方向通常是:

  • 先让业务主线成为第一组织单位
  • 先收回 feature 私有实现,避免继续堆到公共层
  • 先让页面、store 和服务端契约围绕同一模块对齐

19. 公共层越来越大,但真正稳定共享的能力越来越少

表现通常是:composables/utils/components/ 和公共 store 越来越多,但很多能力其实只服务单一业务模块,公共层不断累积历史包袱。

优先看:

对应的重构方向通常是:

  • 先拆基础设施、共享协议和 feature 私有桥接三层
  • 先给共享能力加上真实复用验证标准
  • 先建立从公共层回收到 feature 的降级路径

20. 页面请求已经走本地接口,但接口职责越来越混

表现通常是:页面不再直连后端了,但 server/api 仍然像透传层,请求上下文、聚合和映射逻辑都挤在一起。

优先看:

对应的重构方向通常是:

  • 先拆页面消费层、BFF 接口层和下游适配层
  • 先让 server/api 表达页面契约,而不是原始结构
  • 先把请求上下文准备从接口业务组装里拿出来

21. 动画与业务状态相互污染

表现通常是:一个方法里既改业务状态又触发动画,多个浮层和多个反馈效果散在不同组件里。

优先看:

对应的重构方向通常是:

  • 先分离业务状态和动画状态
  • 先引入交互状态层与动画协调层
  • 先稳定状态链路,再优化动画效果

三、按想沉淀的能力找案例

很多时候你不是在修某个具体项目,而是想提炼一类可复用能力。这时可以按能力类型看文档。

想沉淀页面业务 composable

优先看:

关键词:

  • useTodos
  • useCart
  • useSession
  • usePostFeed
  • useDialogController

想沉淀基础组件上下文体系

优先看:

关键词:

  • provide/inject
  • 组件上下文
  • 字段注册
  • 递归节点上下文

想沉淀扩展协议与桥接层

优先看:

关键词:

  • TableColumn
  • TableCellContext
  • FormRule
  • FieldState
  • render 桥接层

想沉淀递归结构或联动算法

优先看:

关键词:

  • 父子传播
  • 半选态
  • 列表联动
  • 长链路状态同步

想沉淀 SSR / hydration 数据流

优先看:

关键词:

  • 请求级应用工厂
  • 服务端预取
  • 客户端补预取
  • 初始状态注入
  • 水合边界

想沉淀 Nuxt 页面数据获取策略

优先看:

关键词:

  • useAsyncData
  • useFetch
  • 渲染模式
  • hydration 边界
  • 页面与 composable 分层

想沉淀状态中心与 Pinia store 设计

优先看:

关键词:

  • 全局状态边界
  • 业务域 store
  • defineStore
  • Vuex 迁移
  • Nuxt store 组织

想沉淀认证链路与权限边界

优先看:

关键词:

  • useAuthSession
  • 请求适配层
  • route meta
  • 登录回跳
  • 权限守卫

想沉淀路由壳层与页面缓存边界

优先看:

关键词:

  • RouterView 插槽
  • KeepAlive
  • route.meta.layout
  • route.meta.keepAlive
  • activated / deactivated

想沉淀错误边界与客户端降级能力

优先看:

关键词:

  • ClientOnly
  • NuxtErrorBoundary
  • fallback
  • 重试面板
  • 错误隔离

想沉淀异步组件与懒加载边界

优先看:

关键词:

  • import()
  • Suspense
  • loading / error / timeout
  • fallback
  • retry

想沉淀Nuxt运行时与插件注入边界

优先看:

关键词:

  • server/middleware
  • app/middleware
  • defineNuxtPlugin
  • 运行时注入
  • useNuxtApp()

想沉淀Nuxt生命周期与副作用时机边界

优先看:

关键词:

  • 生命周期分段
  • SSR
  • hydration
  • onMounted
  • 副作用清理

想沉淀Nuxt自动导入与隐式依赖边界

优先看:

关键词:

  • 自动导入
  • imports.dirs
  • composable 公共入口
  • feature 内部实现
  • 隐式依赖

想沉淀Nuxt组合式能力分层与页面编排边界

优先看:

关键词:

  • 页面业务 composable
  • 页面入口层
  • feature 步骤层
  • store 归属
  • 页面编排

想沉淀Nuxt业务模块与feature目录边界

优先看:

关键词:

  • features/
  • 业务模块
  • 公共层收口
  • 模块入口
  • 目录边界

想沉淀Nuxt应用公共层与共享能力治理

优先看:

关键词:

  • 应用公共层
  • 共享协议
  • 伪复用
  • 能力回收
  • 自动导入暴露面

想沉淀Nuxt Server Routes与BFF接口边界

优先看:

关键词:

  • server/api
  • BFF
  • 页面契约
  • 服务组装层
  • 下游适配层

想沉淀Nuxt路由规则与混合渲染边界

优先看:

关键词:

  • routeRules
  • swr
  • isr
  • prerender
  • ssr: false

想沉淀动画协调层与复杂交互设计

优先看:

关键词:

  • 动画状态
  • 交互状态
  • 动画协调层
  • 浮层统一管理
  • transform 友好动画

四、按“症状”快速定位

如果你手上是一个还没分类好的 Vue demo,可以直接从下面这些常见症状出发:

症状:一个页面文件特别大

先看:

症状:一个交互会带动多个区域一起变化

先看:

症状:组件之间靠名字或事件字符串通信

先看:

症状:组件可扩展,但越扩展越乱

先看:

症状:首屏数据和客户端接管不一致

先看:

症状:Nuxt 页面数据获取方式越来越乱

先看:

症状:store 越来越大,什么都往里放

先看:

症状:登录、请求和页面准入总是互相打架

先看:

症状:页面一切换就丢状态,根组件也越来越重

先看:

症状:某个模块一报错,整页体验就开始崩

先看:

症状:页面能跑,但异步模块加载体验越来越碎

先看:

症状:Nuxt 能跑,但运行时边界越来越说不清

先看:

症状:Nuxt 能跑,但执行时机越来越说不清

先看:

症状:Nuxt import 很少,但依赖关系越来越说不清

先看:

症状:页面里的 composable 很多,但编排边界越来越说不清

先看:

症状:feature 目录有了,但还是很难顺着目录读懂业务

先看:

症状:公共目录越来越大,但越来越难判断哪些真的能共享

先看:

症状:页面不直连后端了,但接口层越来越像大杂烩

先看:

症状:Nuxt 页面很多,但响应策略越来越说不清

先看:

症状:一个交互会触发多个区域一起变化且越来越难管

先看:

症状:重构时不知道该先拆模板还是先抽状态

先看:

五、一个推荐阅读路径

如果以后要把更多 Vue 练习项目都纳入这套体系,推荐按下面的阅读顺序使用:

先建立总方法

先读 Vue练习项目重构统一框架

再看页面型案例

按顺序读:

这三篇最适合建立“页面重构”直觉。

再看基础组件型案例

按顺序读:

这三篇最适合建立“组件库能力设计”直觉。

六、这份导航图真正沉淀了什么

统一框架解决的是“怎么重构”,而这份导航图解决的是“先看哪篇”。两者配合以后,整套文档就从一组分散笔记,变成了一套可以反复使用的 Vue 重构知识结构。

以后继续整理新的 Vue 案例时,也可以直接往这张导航图里扩展:

  • 增加新的项目类型分类
  • 增加新的复杂度中心分类
  • 增加新的能力沉淀分类
  • 增加新的症状定位入口

这样文档体系会越来越像一个真正可检索、可扩展、可复用的方法库,而不只是案例堆积。

共 20 个模块,1301 篇 Markdown 文档。