Composition API 设计思想(第11节)

一、为什么要引入 Composition API?------Vue 团队是真的被逼急了 😅

1️⃣ Options API 的"结构性问题",不是写法问题

Options API 最大的问题不是"老",而是当组件复杂后,逻辑会被强行拆散

来看一个典型业务:用户列表 + 搜索 + 请求 + loading + 错误处理

在 Options API 里,你会得到这样的结构:

js 复制代码
export default {
  data() {
    return {
      list: [],
      loading: false,
      keyword: '',
      error: null
    }
  },
  methods: {
    async fetchList() { /* ... */ },
    onSearch() { /* ... */ }
  },
  watch: {
    keyword() { /* 触发搜索 */ }
  },
  created() {
    this.fetchList()
  }
}

问题在哪?

  • 一个"列表请求"的逻辑,被拆进了 data / methods / watch / 生命周期
  • 逻辑的时间顺序业务意图被结构打断
  • 想复用?复制一整坨 options,再删删改改 😵‍💫

👉 Vue 官方在 RFC 里就点名了这个问题:
Options API 不利于复杂逻辑的组织与复用。

2️⃣ Composition API 的核心动机:按"逻辑"组织代码

Composition API 的第一性原理只有一句话:

把"相关的逻辑"写在一起,而不是把"同类型的代码"写在一起。

这不是语法升级,这是代码组织方式的升级

二、逻辑复用问题:Composition API 是怎么"正面硬刚"的?🧠

1️⃣ Options API 的复用方式有多痛?

mixins:历史遗留之痛
js 复制代码
mixins: [listMixin, searchMixin]

痛点你肯定踩过:

  • 命名冲突(methods/data 谁覆盖谁?)
  • 来源不透明(这个方法到底从哪来的?)
  • 逻辑耦合严重(删一个 mixin,全组件爆炸)

👉 mixin 最大的问题:不是显式依赖

2️⃣ Composition API:用"函数"做逻辑单元

Composition API 的复用单位不是组件,是 函数(Composable)

js 复制代码
export function useList() {
  const list = ref([])
  const loading = ref(false)

  async function fetchList() {
    loading.value = true
    // ...
    loading.value = false
  }

  return { list, loading, fetchList }
}

这一下,问题全解决了:

  • 依赖显式(import 什么就用什么)
  • 命名空间天然隔离
  • 可组合、可测试、可拆分

👉 逻辑像乐高,而不是像面团。

三、对比 Options API:不是"谁淘汰谁",而是"谁更适合复杂度"⚖️

1️⃣ 写法对比(同一个功能)

Options API(逻辑被拆散)
js 复制代码
data() { return { count: 0 } }
methods: {
  inc() { this.count++ }
}
Composition API(逻辑内聚)
js 复制代码
const count = ref(0)
const inc = () => count.value++

看起来只是"换个地方写",但一旦功能多起来,差距会指数级放大。

2️⃣ 思维模型对比

维度 Options API Composition API
组织方式 按配置类型 按业务逻辑
复用能力 mixins(弱) composables(强)
类型推导 困难 天生友好
可拆分性 极强
大型项目 易失控 更可维护

👉 Options API 不是不能用,而是复杂度一高就很吃力

四、可维护性分析:Composition API 为什么更适合"活得久"的项目?🧩

1️⃣ 可维护性 = 可理解性 + 可修改性

Composition API 在这两点上优势非常明显:

✅ 逻辑集中
js 复制代码
// useSearch.ts
export function useSearch(fetcher) {
  const keyword = ref('')
  watch(keyword, () => fetcher(keyword.value))
  return { keyword }
}

谁看这段代码都知道:

"哦,这是搜索逻辑。"

2️⃣ 对 TypeScript 极其友好(这是 Vue3 的关键战场)

ts 复制代码
export function useUser() {
  const user = ref<User | null>(null)
  function setUser(u: User) {
    user.value = u
  }
  return { user, setUser }
}
  • 自动推导
  • IDE 友好
  • 重构安全

👉 Vue3 + Composition API + TS,不是噱头,是工程现实。

五、实战重构示例:把一个"难维护组件"拆干净 💪

1️⃣ 原始 Options API(节选)

js 复制代码
export default {
  data() {
    return {
      list: [],
      loading: false,
      keyword: ''
    }
  },
  methods: {
    async fetchList() { /* ... */ }
  },
  watch: {
    keyword() {
      this.fetchList()
    }
  },
  mounted() {
    this.fetchList()
  }
}

问题:

  • 请求逻辑 + 搜索逻辑 + 状态全混在一起
  • 无法复用
  • 测试困难

2️⃣ Composition API 重构(分而治之)

useList.ts
ts 复制代码
export function useList() {
  const list = ref([])
  const loading = ref(false)

  async function fetchList(keyword = '') {
    loading.value = true
    // mock fetch
    list.value = []
    loading.value = false
  }

  return { list, loading, fetchList }
}
useSearch.ts
ts 复制代码
export function useSearch(onSearch) {
  const keyword = ref('')
  watch(keyword, () => onSearch(keyword.value))
  return { keyword }
}
组件中组合
ts 复制代码
const { list, loading, fetchList } = useList()
const { keyword } = useSearch(fetchList)

onMounted(() => fetchList())

✨ 重构后的收益:

  • 每段逻辑职责单一
  • 可单独测试
  • 可跨组件复用
  • 阅读成本直线下降

六、一句"醒脑总结"(送你当文章结尾 😏)

Composition API 从来不是为了"写得更高级",

而是为了回答一个更现实的问题:
当你的业务越来越复杂时,你的代码还能不能被人看懂?

所以我最后反问你一句:
如果一年后是你自己来维护这段代码,你希望它长得像 Options API,还是像 Composition API? 😉

相关推荐
六月June June14 小时前
自定义调色盘组件
前端·javascript·调色盘
SY_FC15 小时前
实现一个父组件引入了子组件,跳转到其他页面,其他页面返回回来重新加载子组件函数
java·前端·javascript
糟糕好吃15 小时前
我让 AI 操作网页之后,开始不想点按钮了
前端·javascript·后端
陈天伟教授15 小时前
人工智能应用- 天文学家的助手:08. 星系定位与分类
前端·javascript·数据库·人工智能·机器学习
VaJoy15 小时前
给到夯!前端工具链新标杆 Vite Plus 初探
前端·vite
啵啵鱼爱吃小猫咪15 小时前
机械臂阻抗控制github项目-mujoco仿真
开发语言·人工智能·python·机器人
似水明俊德15 小时前
02-C#
开发语言·c#
oem11015 小时前
C++中的享元模式实战
开发语言·c++·算法
似水明俊德15 小时前
01-C#.Net-泛型-面试题
java·开发语言·面试·c#·.net
leonkay16 小时前
Golang语言闭包完全指南
开发语言·数据结构·后端·算法·架构·golang