Skip to content

Vue3 Composition API 详解

Vue3 引入了 Composition API,这是一种全新的组件编写方式,提供了更好的逻辑复用和代码组织能力。本文将深入探讨 Composition API 的核心概念和最佳实践。

什么是 Composition API

Composition API 是 Vue3 提供的一套基于函数的 API,允许我们通过组合函数的方式来组织组件逻辑。与 Options API 相比,Composition API 具有以下优势:

  • 更好的逻辑复用:通过组合函数,可以轻松地在多个组件间共享逻辑
  • 更好的类型推断:对 TypeScript 的支持更加友好
  • 更好的代码组织:相关逻辑可以组织在一起,而不是分散在不同的选项中
  • 更小的包体积:Tree-shaking 更加友好

核心 API 详解

setup 函数

setup 是 Composition API 的入口函数,它在组件创建之前执行,接收 propscontext 作为参数。

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

// 定义响应式数据
const count = ref(0)
const state = reactive({
  name: 'Vue3',
  version: '3.0'
})

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

// 方法
const increment = () => {
  count.value++
}
</script>

ref 和 reactive

refreactive 是创建响应式数据的两种方式:

  • ref:用于基本类型和对象引用,需要通过 .value 访问
  • reactive:用于对象,可以直接访问属性
javascript
import { ref, reactive } from 'vue'

// ref 示例
const count = ref(0)
console.log(count.value) // 0

// reactive 示例
const state = reactive({
  name: 'Vue3',
  count: 0
})
console.log(state.name) // 'Vue3'

computed 计算属性

computed 用于创建计算属性,它会根据依赖的响应式数据自动更新:

javascript
import { ref, computed } from 'vue'

const count = ref(0)
const doubleCount = computed(() => count.value * 2)

// 可写计算属性
const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`
  },
  set(newValue) {
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})

watch 和 watchEffect

watchwatchEffect 用于监听响应式数据的变化:

javascript
import { ref, watch, watchEffect } from 'vue'

const count = ref(0)
const name = ref('Vue3')

// watch - 需要明确指定监听源
watch(count, (newVal, oldVal) => {
  console.log(`count 从 ${oldVal} 变为 ${newVal}`)
})

// watchEffect - 自动追踪依赖
watchEffect(() => {
  console.log(`count: ${count.value}, name: ${name.value}`)
})

生命周期钩子

Composition API 提供了对应的生命周期钩子函数:

javascript
import { onMounted, onUpdated, onUnmounted } from 'vue'

onMounted(() => {
  console.log('组件已挂载')
})

onUpdated(() => {
  console.log('组件已更新')
})

onUnmounted(() => {
  console.log('组件已卸载')
})

组合式函数(Composables)

组合式函数是 Composition API 的核心优势之一,它允许我们将逻辑提取到可复用的函数中:

javascript
// useCounter.js
import { ref, computed } from 'vue'

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

在组件中使用:

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

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

实际应用示例

表单处理

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

const form = reactive({
  username: '',
  email: '',
  password: ''
})

const errors = reactive({})

const validate = () => {
  errors.username = !form.username ? '用户名不能为空' : ''
  errors.email = !form.email ? '邮箱不能为空' : ''
  errors.password = !form.password ? '密码不能为空' : ''
}

const submit = () => {
  validate()
  if (!errors.username && !errors.email && !errors.password) {
    // 提交表单
    console.log('提交表单', form)
  }
}
</script>

API 数据获取

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

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

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

onMounted(() => {
  fetchData()
})
</script>

最佳实践

  1. 使用 <script setup> 语法:这是 Composition API 的推荐写法,更加简洁
  2. 合理使用 ref 和 reactive:基本类型用 ref,对象用 reactive
  3. 提取组合式函数:将可复用的逻辑提取到组合式函数中
  4. 使用 TypeScript:充分利用类型推断和类型检查
  5. 避免过度使用:简单组件仍可使用 Options API

总结

Composition API 为 Vue3 带来了更强大的逻辑复用和代码组织能力。通过合理使用 Composition API,我们可以构建更加模块化、可维护的 Vue 应用。掌握 Composition API 是学习 Vue3 的关键一步,它将帮助你写出更好的代码。


辛田信息技术 · 内部技术分享 · 仅供学习与参考