Files
2026-09-15 15:25:05 +07:00

3.1 KiB

仓库场景示例

示例 A:重构大型视图工具文件

场景

src/views/<module>/utils/ 下某文件同时包含:

  • 路由参数解析,
  • 分页加载,
  • 权限判断,
  • 事件埋点,
  • 章节切换。

目标拆分

  • index.vue(容器页):路由绑定 + hooks 组装。
  • hooks/useEpisodeList.ts:列表分页/刷新逻辑。
  • hooks/useEpisodeAccess.ts:权限校验与付费弹窗逻辑。
  • hooks/useReadEvents.ts:阅读进度与埋点上报逻辑。
  • service/<module>.ts:集中承载接口定义与类型边界。

期望结果

  • 每个 hook 只负责一个业务域。
  • 容器页仅做编排与组件通信。
  • 接口调用统一收敛到 service class 方法。
  • 所有异步动作具备失败兜底状态。

示例 B:新增接口的正确姿势

错误示例

  • .vue 中直接调用 request.get()
  • 返回值不定义类型,使用点到处强转。

正确示例

  1. src/service/<domain>.ts 中新增方法:
    • 入参类型明确,
    • 返回值类型明确,
    • 不混入视图逻辑。
  2. hook 调用 service,并映射到本地状态。
  3. view 仅消费 hook 对外暴露的数据和动作。

示例 C:页面动作的错误处理

必备模式

  • 异步前先 loading = true
  • 使用 try/catch/finally 包裹异步调用。
  • catch 中设置 error = true,并将关键数据恢复到安全默认值。
  • finally 中关闭 loading,避免状态泄漏。

需要避免

  • catch (e) { console.log(e) },但不修改任何状态。
  • 仅在成功分支关闭 loading。

示例 D:页面组件拆分克制

应该拆

  • 用户信息面板、会员卡片、菜单宫格这类具备清晰业务语义的区块。
  • 交互复杂、模板较长,独立后能明显降低 index.vue 理解成本的区块。
  • 已有复用或确定会复用的 UI/业务组件。

不应该拆

  • 只有几行 HTML/CSS 的布局容器。
  • 只接收原样 props 再原样渲染,没有独立语义或交互的小片段。
  • 为了凑 components/ 目录,把一个页面按视觉切片拆成大量一次性组件。

期望结果

  • index.vue 负责页面编排,不变成所有状态和副作用的大杂烩。
  • components/ 数量服务于职责边界,不以“越多越规范”为目标。
  • 简单静态片段可以留在页面或父组件内。

示例 E:大文件拆分触发(mediaContentInfo 类场景)

触发条件

当类似 src/views/acgModule/utils/mediaContentInfo.ts 的文件持续叠加以下逻辑时:

  • 列表分页逻辑,
  • 权限与付费闸门逻辑,
  • 阅读进度与埋点逻辑,
  • 路由同步逻辑。

推荐拆分方案

  1. useMediaEpisodePaging.ts:分页、刷新、列表合并规则。
  2. useMediaEpisodeAccess.ts:权限校验、付费弹窗状态、购买成功处理。
  3. useMediaReadReport.ts:进度计算与埋点派发。
  4. 协调文件保持轻量:仅组装 hooks 并对 view 暴露统一 API。

完成标准

  • 不存在跨多个业务域的“大而全 hook”。
  • 埋点逻辑不直接修改分页状态。
  • 权限逻辑不直接承担列表拉取职责。