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>

十、学习资源


有问题?欢迎留言讨论!

相关推荐
文心快码BaiduComate2 小时前
百度文心快码全面支持GLM-5
前端·人工智能
unirst19850072 小时前
使用vite打包并部署vue项目到nginx
前端·vue.js·nginx
wordbaby2 小时前
Vue 实战:从零实现“划词标注”与“高亮笔记”功能
前端
上海合宙LuatOS2 小时前
LuatOS核心库API——【fatfs】支持FAT32文件系统
java·前端·网络·数据库·单片机·嵌入式硬件·物联网
wuhen_n2 小时前
JavaScript 手写 new 操作符:深入理解对象创建
前端·javascript
不想秃头的程序员2 小时前
TypeScript 核心基础知识
前端·面试·typescript
派星2 小时前
Day02:认识 AI IDE 工具
前端·人工智能
m0_528749002 小时前
linux编程----目录流
java·前端·数据库
集成显卡2 小时前
前端视频播放方案选型:主流 Web 播放器对比 + Vue3 实战
前端·vue·音视频