Vue 3 Composition API 实战入门指南

发布于2026-03-29 22:30 阅读17次 本文通过实际案例详细介绍 Vue 3 Composition API 的核心用法,涵盖 setup 函数、响应式基础、script-setup 语法、自定义组合式函数、watch 与 watchEffect,以及生命周期钩子等内容。
# Vue 3 Composition API 实战入门指南
Vue 3 引入的 Composition API 是框架近年来最重要的变革之一。相比 Options API,Composition API 提供了更灵活的代码组织方式,尤其在处理复杂逻辑复用时优势明显。本文将通过实际案例,帮助开发者快速掌握 Composition API 的核心用法。
## 为什么需要 Composition API
在 Vue 2 时代,Options API 通过 data、methods、computed、watch 等选项组织代码。这种方式在小型组件中清晰直观,但当组件逻辑变得复杂时,同一个功能的代码会被拆散到多个选项中,维护起来非常困难。比如一个带有搜索和分页的列表组件,相关的状态、方法和副作用分散在各处,阅读和修改都需要在不同选项之间反复跳转。
Composition API 通过组合式函数(Composable)将相关逻辑聚合在一起,解决了这个问题。
## setup 函数与响应式基础
Composition API 的入口是 setup 函数,它在组件创建之前执行,此时 props 已经被解析:
```javascript
import { ref, computed, onMounted } from 'vue'
export default {
props: {
initialCount: { type: Number, default: 0 }
},
setup(props) {
const count = ref(props.initialCount)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
}
onMounted(() => {
console.log('组件已挂载,初始值:', count.value)
})
return { count, doubled, increment }
}
}
```
注意 ref 返回的是一个响应式引用对象,通过 .value 访问和修改值。在模板中则会自动解包,无需 .value。
## 使用 script-setup 简化代码
Vue 3.2 推出了 `<script setup>` 语法糖,进一步简化了 Composition API 的使用。顶层绑定会自动暴露给模板,不需要手动 return:
```vue
<script setup>
import { ref, computed, onMounted } from 'vue'
const props = defineProps({
initialCount: { type: Number, default: 0 }
})
const count = ref(props.initialCount)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
}
onMounted(() => {
console.log('组件已挂载')
})
</script>
```
## reactive 与 ref 的选择
ref 和 reactive 都能创建响应式数据,但适用场景不同。ref 适合基础类型和需要重新赋值的对象,reactive 适合对象的深层响应式:
```javascript
// ref - 可替换整个值
const user = ref({ name: '张三', age: 25 })
user.value = { name: '李四', age: 30 } // 完全替换
// reactive - 适合复杂对象,但不能替换整体
const state = reactive({
list: [],
loading: false,
error: null
})
state.list.push({ id: 1 }) // 直接操作属性
```
实际项目中建议统一使用 ref,避免 reactive 在解构时丢失响应性的问题。
## 自定义组合式函数
Composition API 最大的优势在于逻辑复用。通过自定义 Composable,可以将通用逻辑提取为独立函数:
```javascript
// useFetch.js
import { ref, onMounted } from 'vue'
export function useFetch(url) {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
async function fetch_data() {
loading.value = true
error.value = null
try {
const res = await fetch(url)
data.value = await res.json()
} catch (e) {
error.value = e.message
} finally {
loading.value = false
}
}
onMounted(fetch_data)
return { data, loading, error, fetch_data }
}
```
在组件中使用:
```vue
<script setup>
import { useFetch } from './useFetch'
const { data, loading, error } = useFetch('/api/users')
</script>
<template>
<div v-if="loading">加载中...</div>
<div v-else-if="error">错误:{{ error }}</div>
<ul v-else>
<li v-for="user in data" :key="user.id">{{ user.name }}</li>
</ul>
</template>
```
## watch 与 watchEffect
watch 用于监听特定数据变化并执行副作用,watchEffect 则自动追踪回调中使用的响应式依赖:
```javascript
// watch - 明确指定监听源
watch(count, (newVal, oldVal) => {
console.log(`count 从 ${oldVal} 变为 ${newVal}`)
})
// watchEffect - 自动追踪依赖
watchEffect(() => {
console.log('count 当前值:', count.value)
})
// 监听多个源
watch([firstName, lastName], ([first, last]) => {
fullName.value = first + last
})
```
## 生命周期钩子
Composition API 中的生命周期钩子以 on 前缀命名:onMounted、onUpdated、onUnmounted、onBeforeMount 等。用法与 Options API 完全对应,只是需要在 setup 中调用。由于 setup 在 beforeCreate 和 created 之间执行,这两个钩子不再需要。
## 结语
Composition API 并不是要取代 Options API,而是提供了一个更强大的代码组织工具。对于简单组件,Options API 依然足够好用;对于需要逻辑复用和复杂状态管理的场景,Composition API 则是更优的选择。建议新项目直接采用 script-setup 语法,享受更简洁的开发体验。