Vue 组合式 API 与 选项式 API 全面对比教程

一、前言:Vue 的两种 API 风格

Vue 提供了两种编写组件逻辑的方式:组合式 API (Composition API)选项式 API (Options API)。理解这两种方式的区别和适用场景,对于 Vue 开发者至关重要。

为什么会有两种 API?

  • 选项式 API:Vue 2 的传统方式,按照选项(data、methods 等)组织代码
  • 组合式 API:Vue 3 引入的新方式,基于函数组合逻辑,更适合复杂组件

二、选项式 API (Options API) 详解

1. 基本结构

<script>
export default {
  // 数据选项
  data() {
    return {
      count: 0,
      message: 'Hello Vue!'
    }
  },
  
  // 计算属性
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  },
  
  // 方法
  methods: {
    increment() {
      this.count++
    }
  },
  
  // 生命周期钩子
  mounted() {
    console.log('组件已挂载')
  }
}
</script>

<template>
  <div>
    <p>{{ message }}</p>
    <p>反转: {{ reversedMessage }}</p>
    <button @click="increment">计数: {{ count }}</button>
  </div>
</template>

2. 选项式 API 的特点

  • 按选项组织代码:将代码分为 data、methods、computed 等固定选项
  • this 上下文:通过 this 访问组件实例
  • 隐式响应式:data 返回的对象自动成为响应式
  • 适合简单组件:逻辑较少时结构清晰

3. 生命周期钩子

export default {
  beforeCreate() {},
  created() {},
  beforeMount() {},
  mounted() {},
  beforeUpdate() {},
  updated() {},
  beforeUnmount() {},
  unmounted() {}
}

三、组合式 API (Composition API) 详解

1. 基本结构(<script setup> 语法)

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

// 响应式状态
const count = ref(0)
const message = ref('Hello Vue!')

// 计算属性
const reversedMessage = computed(() => {
  return message.value.split('').reverse().join('')
})

// 方法
function increment() {
  count.value++
}

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

<template>
  <div>
    <p>{{ message }}</p>
    <p>反转: {{ reversedMessage }}</p>
    <button @click="increment">计数: {{ count }}</button>
  </div>
</template>

2. 组合式 API 的特点

  • 基于函数:通过导入函数实现各种功能
  • 逻辑组合:可以自由组织相关代码
  • 显式响应式:需要明确使用 ref/reactive
  • 更好的 TypeScript 支持:类型推断更自然
  • 逻辑复用:可以提取和重用逻辑(组合函数)

3. 核心响应式 API

API用途选项式 API 对应物
ref创建基本类型的响应式数据data 中的基本类型
reactive创建对象的响应式代理data 中的对象
computed创建计算属性computed 选项
watch监听响应式数据变化watch 选项
watchEffect自动追踪依赖的响应式效果-

4. 生命周期钩子对照

选项式 API组合式 API
beforeCreate不需要(直接写在 setup 中)
created不需要(直接写在 setup 中)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted

四、两种 API 的深度对比

1. 代码组织方式

选项式 API

export default {
  data() { /*...*/ },    // 数据
  computed: { /*...*/ }, // 计算属性
  methods: { /*...*/ },  // 方法
  watch: { /*...*/ }     // 监听器
}

组合式 API

// 功能A相关代码
const { x, y } = useFeatureA()

// 功能B相关代码
const { a, b } = useFeatureB()

2. 逻辑复用对比

选项式 API 复用(mixins)

// mixin.js
export default {
  data() {
    return {
      mixinData: 'Mixin Data'
    }
  },
  methods: {
    mixinMethod() { /*...*/ }
  }
}

// 组件中使用
import myMixin from './mixin.js'
export default {
  mixins: [myMixin]
}

组合式 API 复用(组合函数)

// useFeature.js
export function useFeature() {
  const state = ref(null)
  function doSomething() { /*...*/ }
  return { state, doSomething }
}

// 组件中使用
import { useFeature } from './useFeature.js'
const { state, doSomething } = useFeature()

3. 类型支持对比

  • 选项式 API:类型推断有限,特别是在使用 mixins 时
  • 组合式 API:天然支持 TypeScript,类型推断更准确

五、何时使用哪种 API?

选项式 API 适合:

  • 小型到中型项目
  • 简单组件开发
  • 熟悉 Vue 2 的开发者
  • 需要快速原型开发时

组合式 API 适合:

  • 大型复杂项目
  • 需要更好逻辑组织的组件
  • 需要逻辑复用的场景
  • TypeScript 项目
  • 团队希望统一代码风格

六、组合式 API 进阶技巧

1. 自定义组合函数示例

// useCounter.js
import { ref } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  function increment() {
    count.value++
  }
  
  function decrement() {
    count.value--
  }
  
  function reset() {
    count.value = initialValue
  }
  
  return {
    count,
    increment,
    decrement,
    reset
  }
}

组件中使用:

<script setup>
import { useCounter } from './useCounter'

const { count, increment } = useCounter(10)
</script>

<template>
  <button @click="increment">Count: {{ count }}</button>
</template>

2. 异步状态管理

<script setup>
import { ref } from 'vue'

const data = ref(null)
const loading = ref(false)
const error = ref(null)

async function fetchData() {
  loading.value = true
  error.value = null
  try {
    const response = await fetch('/api/data')
    data.value = await response.json()
  } catch (err) {
    error.value = err
  } finally {
    loading.value = false
  }
}

// 立即获取数据
fetchData()
</script>

3. 组件通信

<!-- Parent.vue -->
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'

const msg = ref('Hello from parent')
</script>

<template>
  <Child v-model="msg" />
</template>

<!-- Child.vue -->
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

七、迁移策略:从选项式到组合式

1. 渐进式迁移

  • 新组件使用组合式 API
  • 旧组件逐步重构
  • 混合使用(在选项式组件中使用 setup 选项)

2. 对应关系记忆卡

选项式 API组合式 API
this不需要,直接访问变量
data()ref()reactive()
methods普通函数
computedcomputed()
watchwatch()watchEffect()
生命周期钩子onXxx() 系列函数
propsdefineProps()
emitsdefineEmits()
mixins组合函数

八、常见问题解答

1. 两种 API 可以混用吗?

可以,但不推荐。在 Vue 3 中,你可以在组件中使用 setup() 选项来使用组合式 API,同时保留其他选项。

2. 组合式 API 更难学吗?

对于 Vue 新手,选项式 API 可能更容易上手。但有其他框架经验的开发者,组合式 API 可能更直观。

3. 性能有差异吗?

两种 API 在性能上没有显著差异,组合式 API 在某些场景下可能有轻微优势。

4. 公司项目该用哪种?

新项目推荐组合式 API,旧项目可以逐步迁移。团队统一风格最重要。

九、总结

Vue 的两种 API 风格各有优势:

  • 选项式 API:结构清晰,学习曲线平缓,适合简单场景
  • 组合式 API:灵活强大,便于逻辑复用和组织,适合复杂场景

建议开发者:

  1. 先掌握选项式 API 理解 Vue 核心概念
  2. 逐渐过渡到组合式 API
  3. 根据项目需求和个人偏好选择合适的方式
  4. 大型项目推荐统一使用组合式 API

组合式 API 代表了 Vue 的未来发展方向,特别是对于复杂应用和需要良好 TypeScript 支持的项目。选项式 API 仍会长期支持,适合维护旧项目和简单场景。

创作不易,如果您都看到这里了,可以给我一个点赞、收藏并关注一下么?您的支持与喜爱是激励我创作的最大动力!

如果内容有误请及时联系我进行修改!

### Vue3 中组合式 API 选项式 API 的主要差异及使用场景 #### 主要差异 1. **代码组织方式** 组合式 API 通过 `setup` 函数将组件的逻辑集中在一个地方,便于管理复用。而选项式 API 将组件的逻辑分散在多个选项中(如 `data`、`methods`、`computed` 等),虽然直观但可能在复杂组件中导致逻辑分散[^1]。 2. **响应式数据定义** - 组合式 API 使用 `reactive` 或 `ref` 明确地定义响应式数据,灵活性更高[^4]。 - 选项式 API 则通过 `data` 函数返回一个对象来定义响应式数据[^2]。 3. **逻辑复用** - 组合式 API 提供了更好的逻辑复用能力,可以通过自定义函数或组合函数(Composables)实现跨组件的逻辑共享[^3]。 - 选项式 API 在逻辑复用方面较为局限,通常依赖于混入(Mixins),但混入可能导致命名冲突可维护性问题[^2]。 4. **TypeScript 支持** 组合式 API 更适合 TypeScript 配合使用,能够提供更好的类型推断开发体验。 5. **生命周期钩子** - 组合式 API 使用 `onMounted`、`onUnmounted` 等函数替代选项式 API 的 `mounted`、`unmounted` 等钩子。 - 选项式 API 的生命周期钩子直接作为组件选项的一部分[^2]。 #### 使用场景 1. **组合式 API** - 适用于大型应用复杂组件,尤其是需要逻辑复用或 TypeScript 深度集成时[^3]。 - 示例代码: ```javascript import { ref, reactive, onMounted } from 'vue'; export default { setup() { const count = ref(0); const state = reactive({ name: 'Vue3' }); onMounted(() => { console.log('Component mounted'); }); function increment() { count.value++; } return { count, state, increment }; } }; ``` 2. **选项式 API** - 更适合小型项目或快速原型开发,因其直观性较低的学习曲线[^3]。 - 示例代码: ```javascript export default { data() { return { count: 0, name: 'Vue3' }; }, methods: { increment() { this.count++; } }, mounted() { console.log('Component mounted'); } }; ``` #### 总结 两种 API 并非互相排斥,而是互为补充。开发者可以根据项目需求个人偏好灵活选择。对于需要高度复用性强类型支持的场景,推荐使用组合式 API;而对于简单项目或团队熟悉选项式 API 的情况,选项式 API 是更高效的选择。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值