Vue 选项式 API vs 组合式 API:区别全解析

前言

如果你刚开始学习 Vue 3,你可能会听到两个词:选项式 API组合式 API。它们是什么?有什么区别?应该用哪个?这篇文章用最简单的方式讲清楚。


一、什么是选项式 API?

选项式 API 是 Vue 2 时代的经典写法,也是 Vue 3 仍然支持的写法。

特点:按类型分组

代码按照 datamethodscomputed 等选项分类:

复制代码
export default {
  data() {
    return {
      count: 0,
      name: '张三'
    }
  },
  methods: {
    add() {
      this.count++
    },
    sayHi() {
      console.log('我是' + this.name)
    }
  },
  computed: {
    double() {
      return this.count * 2
    }
  },
  mounted() {
    console.log('组件挂载了')
  }
}

关键点:

  • ✅ 结构清晰,新手友好
  • ✅ 每个选项有明确的用途
  • ❌ 相关的代码被分散到不同位置
  • ❌ 需要用 this 访问数据

二、什么是组合式 API?

组合式 API 是 Vue 3 新增的写法,更灵活、更强大。

特点:按功能分组

相关的代码写在一起:

复制代码
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    // 计数相关功能
    const count = ref(0)
    const double = computed(() => count.value * 2)
    const add = () => {
      count.value++
    }

    // 用户信息相关功能
    const name = ref('张三')
    const sayHi = () => {
      console.log('我是' + name.value)
    }

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

    return { count, double, add, name, sayHi }
  }
}

更简洁的 <script setup> 写法(推荐):

复制代码
<script setup>
import { ref, computed, onMounted } from 'vue'

// 计数相关功能
const count = ref(0)
const double = computed(() => count.value * 2)
const add = () => count.value++

// 用户信息相关功能
const name = ref('张三')
const sayHi = () => console.log('我是' + name.value)

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

关键点:

  • ✅ 相关代码组织在一起
  • ✅ 不需要 this
  • ✅ 更容易复用逻辑(Composables)
  • ❌ 需要理解响应式 API(ref、reactive)

三、核心区别:this 的使用

选项式 API:到处用 this

复制代码
export default {
  data() {
    return {
      name: '张三',
      count: 0
    }
  },
  methods: {
    sayHi() {
      // 必须用 this 访问 data
      console.log(this.name)
    },
    add() {
      // 必须用 this 访问其他数据
      this.count++
    }
  }
}

为什么需要 this

因为 datamethodscomputed 写在不同的地方,它们之间需要 this 来连接。

组合式 API:不需要 this

复制代码
import { ref } from 'vue'

export default {
  setup() {
    const name = ref('张三')
    const count = ref(0)

    const sayHi = () => {
      // 直接用,不需要 this
      console.log(name.value)
    }

    const add = () => {
      // 直接用,不需要 this
      count.value++
    }

    return { name, count, sayHi, add }
  }
}

为什么不需要 this

因为所有变量都在 setup() 函数的同一个作用域内,就像普通 JavaScript 一样直接使用。


四、生活比喻

选项式 API = 餐厅点餐

复制代码
菜单分类:
  - 前菜区
  - 主菜区
  - 甜品区

你需要的东西分散在不同区域
需要说"我要主菜区的牛排"

组合式 API = 自助餐

复制代码
所有东西都在一个台子上
你可以自由组合:
  - 牛排配薯条(相关的一组)
  - 沙拉配汤(相关的一组)

需要什么直接拿

五、完整对比示例

示例:一个用户信息表单

选项式 API:
复制代码
export default {
  data() {
    return {
      form: {
        username: '',
        phone: '',
        email: ''
      },
      loading: false,
      rules: {
        username: [{ required: true, message: '请输入用户名' }]
      }
    }
  },
  computed: {
    isValid() {
      return this.form.username && this.form.phone
    }
  },
  methods: {
    async submit() {
      this.loading = true
      // 提交逻辑...
      this.loading = false
    },
    reset() {
      this.form.username = ''
      this.form.phone = ''
      this.form.email = ''
    }
  }
}
组合式 API:
复制代码
<script setup>
import { ref, computed } from 'vue'

// 表单数据
const form = ref({
  username: '',
  phone: '',
  email: ''
})

// 表单验证规则
const rules = {
  username: [{ required: true, message: '请输入用户名' }]
}

// 加载状态
const loading = ref(false)

// 计算属性
const isValid = computed(() => {
  return form.value.username && form.value.phone
})

// 提交方法
const submit = async () => {
  loading.value = true
  // 提交逻辑...
  loading.value = false
}

// 重置方法
const reset = () => {
  form.value.username = ''
  form.value.phone = ''
  form.value.email = ''
}
</script>

六、优缺点对比

对比项 选项式 API 组合式 API
上手难度 ⭐ 简单 ⭐⭐⭐ 需要学习新概念
代码组织 按类型分组 按功能分组
this 使用 到处需要 this 不需要 this
逻辑复用 Mixins(容易冲突) Composables(清晰)
TypeScript 支持一般 支持很好
代码量 较多(boilerplate 多) 较少
适合场景 简单组件、小项目 复杂逻辑、大项目

七、什么时候用哪个?

用选项式 API:

  • ✅ 你刚学 Vue,想要简单易懂
  • ✅ 组件逻辑简单,代码量少
  • ✅ 团队成员更熟悉 Vue 2

用组合式 API:

  • ✅ 项目复杂,逻辑多
  • ✅ 需要复用逻辑(多个组件用同一套逻辑)
  • ✅ 想要更好的 TypeScript 支持
  • ✅ 新项目,没有历史包袱

八、实际项目例子

看看你项目中的代码:

stores/user.js(组合式 API)

复制代码
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useUserStore = defineStore('user', () => {
  // 状态
  const user = ref({})
  const token = ref("")

  // 方法
  function login(username, password) {
    // ...
  }

  function logout() {
    // ...
  }

  // 返回
  return { user, token, login, logout }
})

为什么用组合式?

  • usertokenloginlogout 都是用户相关的功能
  • 放在一起,逻辑清晰
  • 不需要 this.userthis.token,直接用

九、总结

核心区别一句话:

写法 特点
选项式 API 代码按类型分类(data、methods 分开),用 this 连接
组合式 API 代码按功能分类(相关的一起),不用 this

我的建议:

  • 新手:先学选项式 API,理解 Vue 的基本概念
  • 进阶:转向组合式 API,享受更好的代码组织
  • 新项目 :直接用组合式 API + <script setup>

十、学习资源


有问题?欢迎留言讨论!

相关推荐
万少7 小时前
Vibe Coding不停歇,移动端 TRAE SOLO 让你用手机也能编程啦
前端·javascript·后端
kyriewen118 小时前
WebAssembly:前端界的“外挂”,让C++代码在浏览器里跑起来
开发语言·前端·javascript·c++·单元测试·ecmascript
烛衔溟9 小时前
TypeScript 接口的基本使用 —— 定义对象形状
前端·javascript·typescript
铁皮饭盒9 小时前
成为AI全栈 - 第3课:路由 RESTful Elysia 状态码 设计规范
前端·后端·全栈
顾昂_9 小时前
Web 性能优化完全指南
前端·面试·性能优化
IT乐手10 小时前
Claude Code + Qwen 的配置方法
javascript·claude
前端程序媛-Tian10 小时前
前端 AI 提效实战:从 0 到 1 打造团队专属 AI 代码评审工具
前端·人工智能·ai
支付宝体验科技10 小时前
Ant Design Pro v6.0.0 发布
前端
T畅N11 小时前
审批流设计器(前端)
前端·elementui·vue·html·流程图·js
AlunYegeer11 小时前
JAVA,以后端的视角理解前端。在全栈的路上迈出第一步。
java·开发语言·前端