把 300 行的 Vue3 组件拆成 composable:一次真实重构

举报
yd_264617019 发表于 2026/10/16 21:56:47 2026/10/16
【摘要】 接手了一个历史页面,单个SFC接近300行,template里混着五段逻辑:问卷加载、倒计时、答案暂存、草稿恢复、埋点上报。改任何一个地方都要在几百行里上下跳,review也难受。这周下决心用Vue3的组合式API拆了一遍,记录下思路。拆分原则很简单:按「职责」而不是按「代码类型」分组。原来的写法是data里二十个字段、methods里十几个函数,彼此耦合;重构后每个职责一个composab...

接手了一个历史页面,单个 SFC 接近 300 行,template 里混着五段逻辑:问卷加载、倒计时、答案暂存、草稿恢复、埋点上报。改任何一个地方都要在几百行里上下跳,review 也难受。这周下决心用 Vue3 的组合式 API 拆了一遍,记录下思路。

拆分原则很简单:按「职责」而不是按「代码类型」分组。原来的写法是 data 里二十个字段、methods 里十几个函数,彼此耦合;重构后每个职责一个 composable,各自持有自己的状态和方法。

以倒计时为例,抽出来的 useCountdown 长这样:

import { ref, onUnmounted } from 'vue'

export function useCountdown(seconds: number) {
  const left = ref(seconds)
  const timer = setInterval(() => {
    left.value -= 1
    if (left.value <= 0) clearInterval(timer)
  }, 1000)
  // 组件卸载时清理,避免定时器泄漏
  onUnmounted(() => clearInterval(timer))
  return { left }
}

关键点在于 onUnmounted 可以写在 composable 里,只要这个函数在 setup 中被调用,生命周期就会正确挂到宿主组件上。这一点比 Vue2 的 mixin 干净太多——mixin 里的变量来源不明,composable 的来源一目了然。

草稿恢复那段抽成了 useDraft,内部用 localStorage 做 key-value 存取,对外只暴露 save 和 restore 两个方法。埋点抽成 useTracker 后,页面里只剩一个统一的 report 函数入口,运营要加事件名也不用动业务代码。

拆完之后的 SFC 只剩 80 行左右,template 负责展示,setup 里是四行解构调用。后续有个同事要在另一个活动页复用倒计时,直接 import 就能用,这大概就是这次重构最直接的收益。

几点体会:第一,不要为了拆而拆,两三行逻辑不值得一个文件;第二,composable 的返回值用 ref 而不是 reactive,避免解构后失去响应性,真要解构 reactive 就配 toRefs;第三,命名统一用 useXxx,参数尽量支持传入回调而非把回调写死,复用时会灵活很多。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。