【vue】选项式api与组合式api

Vue 选项式 API 与组合式 API 的对比与选择指南(2025–2026 视角)

Vue 目前(Vue 3 + Vue 3.5+)同时支持两种主要代码组织方式:

  • 选项式 API(Options API)—— Vue 2 的经典写法,Vue 3 完全兼容
  • 组合式 API(Composition API)—— Vue 3 引入的新范式,<script setup> 是其最常用语法糖

下面用真实场景对比的方式,帮助你清晰理解两者的差异、优缺点以及实际项目中该如何选择。

1. 核心对比表格(2025–2026 真实项目视角)

维度选项式 API (Options API)组合式 API (Composition API) + <script setup>胜出方(大多数场景)
代码组织方式按“选项”分组:data、methods、computed、watch…按“逻辑关注点”自由组合组合式
逻辑复用能力mixin、extends(容易命名冲突、来源不清晰)composable 函数(清晰、类型友好、可树摇)组合式 ★★★★★
TypeScript 支持中等(需要大量 as any 或类型断言)极好(类型推导优秀,ref/reactive 天然支持)组合式 ★★★★★
代码量(中大型组件)较多(setup 里逻辑分散在不同选项)更少、更紧凑(相关逻辑写在一起)组合式
学习曲线(新手)较低(结构固定,容易理解“什么放在哪里”)较高(需要理解 ref、reactive、toRefs、生命周期钩子)选项式(初期)
学习曲线(有经验者)中等(大型组件容易变成“意大利面条”)较低(逻辑清晰,可读性高)组合式
性能几乎相同几乎相同(<script setup> 甚至稍有编译期优化)平手
社区趋势(2025–2026)仍然大量维护中的老项目在使用新项目、官方文档、VitePress、Nuxt 3、Element Plus 等主流库默认推荐组合式
官方推荐兼容并继续支持,但新功能优先在组合式中实现官方主推,未来新特性(如 <script setup> 的宏)优先组合式

2. 代码对比(同一个功能两种写法)

需求:一个计数器组件,支持:

  • 显示 count
  • 双倍计算属性 double
  • watch count 变化打印日志
  • 按钮 +1、-1

选项式 API(Vue 2 / Vue 3 兼容写法)

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ double }}</p>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },

  computed: {
    double() {
      return this.count * 2
    }
  },

  watch: {
    count(newVal, oldVal) {
      console.log(`count 从 ${oldVal} 变为 ${newVal}`)
    }
  },

  methods: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    }
  },

  mounted() {
    console.log('组件挂载完成')
  }
}
</script>

组合式 API + <script setup>(Vue 3 推荐写法)

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ double }}</p>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 计算属性
const double = computed(() => count.value * 2)

// 方法
const increment = () => count.value++
const decrement = () => count.value--

// 侦听器
watch(count, (newVal, oldVal) => {
  console.log(`count 从 ${oldVal} 变为 ${newVal}`)
})

// 生命周期
onMounted(() => {
  console.log('组件挂载完成')
})
</script>

3. 组合式 API 的真正优势在“中大型组件”和“逻辑复用”

真实场景对比:一个包含表单校验、远程搜索、分页、权限控制的“用户管理表格”组件

选项式写法很容易出现:

  • data 里 20+ 个属性
  • methods 里 15+ 个方法
  • watch 里散落多个侦听器
  • 生命周期钩子重复写相似的逻辑

组合式写法可以把相关逻辑聚合在一起:

<script setup>
import { ref, watch, onMounted } from 'vue'
import { useForm } from '@/composables/useForm'
import { useTable } from '@/composables/useTable'
import { usePermission } from '@/composables/usePermission'

// 表单逻辑
const { form, validate, resetForm } = useForm()

// 表格逻辑
const { dataSource, pagination, fetchData, loading } = useTable()

// 权限逻辑
const { hasEditPerm, hasDeletePerm } = usePermission('user:manage')

// 统一加载数据
onMounted(fetchData)
</script>

→ 每个 composable 函数都是可独立测试、可复用、可类型推导的模块。

4. 2025–2026 年实际项目中的选择建议

项目类型推荐写法理由简述
全新项目(Vue 3)组合式 + <script setup>官方主推、生态最好、类型支持最强
维护中的 Vue 2 项目继续选项式最小改动成本
Vue 2 → Vue 3 迁移项目选项式 + 组合式 混用逐步把复杂组件改成组合式
中大型组件(>200行)强烈推荐组合式逻辑组织清晰度差距非常明显
需要大量逻辑复用组合式(composable)mixin 几乎被淘汰
团队新手较多先用选项式,逐步过渡学习曲线更平滑
追求极致开发体验 + TS组合式 + <script setup>当前最佳实践

5. 快速判断:我该用哪一种?

问自己这几个问题(按优先级):

  1. 组件是否已经/即将超过 150–200 行?→ 是 → 组合式
  2. 是否大量使用 TypeScript?→ 是 → 组合式
  3. 是否需要把一段逻辑在多个组件复用?→ 是 → 组合式(composable)
  4. 团队大部分人 Vue 2 经验丰富但 Vue 3 刚上手?→ 先选项式,逐步过渡
  5. 是全新项目或新模块?→ 组合式

大多数现代 Vue 3 项目(尤其是 2024 年后新建的)已经默认使用 <script setup> + 组合式 API

如果你现在还在犹豫,可以先在一个新页面/新组件里尝试用 <script setup> 写一次,感受一下逻辑组织上的差异,大部分人写过 2–3 个组件后就会倾向于组合式。

有具体组件代码想对比两种写法,或者想看某个典型场景(表单 + 表格 + 弹窗)的组合式写法示例吗?可以直接贴代码或描述需求~

文章已创建 4357

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部