Vue 3 组合式 API 入门指南
Vue 3 组合式 API 入门指南
从 Options API 到 Composition API
在 Vue 2 时代,Options API 是唯一的开发模式——通过 data、methods、computed、watch 等选项来组织组件逻辑。这种模式在小项目中直观清晰,但随着应用复杂度提升,问题逐渐暴露。
想象一个同时处理用户信息、搜索过滤、分页加载、表单校验的组件:data 里堆满所有状态,methods 里塞满所有方法,computed 里挤满所有派生值——你要理解“用户信息”这一个功能,得在四个选项之间来回跳转。组件一旦超过 200 行,维护起来就像在一碗面条里找一根特定的面。这就是 Options API 的 “面条式代码”问题。
Vue 3 引入的组合式 API(Composition API)正是为了解决这一痛点。它是一组基于函数的 API,允许我们使用导入的函数而非声明选项来编写 Vue 组件。
一个形象的类比:Options API 是把所有笔放一个抽屉、所有本子放一个抽屉;而 Composition API 是把“写周报”需要的东西放一起,“画设计稿”需要的东西放一起——按功能组织代码,而不是按类型分类。
核心概念详解
1. setup():组合式 API 的入口
setup() 是组合式 API 的入口点,在组件实例创建之前、props 解析之后执行。这意味着:
- 在
setup()中无法访问this(组件实例尚未创建) setup()返回的所有内容都会暴露给模板
实际开发中,更推荐使用 <script setup> 语法糖——它大幅减少了样板代码,让组合式 API 的使用更加简洁:
vue
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
onMounted(() => {
console.log(`初始值为 ${count.value}`)
})
</script>
2. ref 与 reactive:响应式数据双核心
Vue 3 的响应式系统基于 Proxy 重构,从根本上解决了 Vue 2 中无法监听数组索引变化、对象新增属性等局限。
ref() —— 创建响应式数据的“万能工具”:
javascript
import { ref } from 'vue'
const count = ref(0) // 基本类型
const user = ref({ name: 'John' }) // 对象也可以
const items = ref(['a', 'b']) // 数组也可以
// 访问和修改必须通过 .value
count.value++
user.value.name = 'Jane'
ref 的本质是一个包装对象 { value: 0 },通过 getter/setter 劫持 value 属性来实现响应式。
reactive() —— 专为对象设计的响应式代理:
javascript
import { reactive } from 'vue'
const state = reactive({
count: 0,
user: { name: 'John', age: 30 }
})
// 直接访问属性,无需 .value
state.count++
state.user.age++ // 嵌套属性也是响应式的
reactive 通过 Proxy 代理整个对象,任何属性的读写都会被拦截。
如何选择?
| 场景 | 推荐 | 原因 |
|---|---|---|
| 基本类型(number/string/boolean) | ref | reactive 不支持基本类型 |
| 组合式函数返回值 | ref | 更灵活,便于解构 |
| 可能被解构的场景 | ref | 配合 toRefs 可安全解构 |
| 复杂对象/表单状态 | reactive | 直接访问属性,更自然 |
小技巧:如果不确定用什么,就用 ref,它更灵活。
3. computed 与 watch:派生状态与副作用
computed —— 自动缓存的计算属性,仅在依赖变化时重新计算:
javascript
import { computed, ref } from 'vue'
const firstName = ref('John')
const lastName = ref('Doe')
// 只读计算属性
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
// 可写计算属性(带 setter)
const double = computed({
get: () => count.value * 2,
set: (val) => { count.value = val / 2 }
})
watch 与 watchEffect —— 响应式副作用控制:
javascript
import { watch, watchEffect, ref } from 'vue'
const count = ref(0)
const user = reactive({ name: 'John' })
// watch:显式指定依赖,可获得新旧值
watch(
() => count.value,
(newVal, oldVal) => {
console.log(`count 从 ${oldVal} 变为 ${newVal}`)
}
)
// watchEffect:自动追踪依赖,立即执行
watchEffect(() => {
console.log(`用户名是 ${user.name}`) // 自动追踪 user.name
})
选择策略:需要知道旧值时用 watch;依赖关系复杂时优先 watchEffect。
4. 生命周期钩子
组合式 API 通过 onXxx 系列函数统一管理生命周期,支持条件式调用和多次注册:
javascript
import { onMounted, onUpdated, onUnmounted } from 'vue'
onMounted(() => {
// DOM 挂载完成后执行
console.log('组件已挂载')
})
onUnmounted(() => {
// 组件卸载时清理资源(事件监听、定时器等)
clearInterval(timer)
})
生命周期映射关系:beforeCreate/created → setup() 本身;mounted → onMounted;updated → onUpdated;destroyed → onUnmounted。
为什么使用组合式 API?
1. 更好的逻辑复用
Options API 依赖 Mixin 实现逻辑复用,但存在作用域不清晰、命名冲突、类型推断困难等致命缺陷。
组合式 API 通过 组合式函数(Composables) 实现逻辑复用:
javascript
// useFetch.js —— 可复用的数据请求逻辑
import { ref, onMounted } from 'vue'
export function useFetch(url) {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
onMounted(async () => {
try {
const response = await fetch(url)
data.value = await response.json()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
})
return { data, loading, error }
}
任意组件中只需一行 const { data, loading } = useFetch(‘/api/users’) 即可复用完整逻辑。
组合式 API 的逻辑复用能力催生了 VueUse——一个不断壮大的组合式函数工具集,提供了从鼠标追踪到防抖节流等数百个开箱即用的 composables。
2. 更灵活的代码组织
Options API 按类型(data/methods/computed)组织代码;组合式 API 按功能聚合相关逻辑。对比同一个“用户管理”功能:
Options API:data 里定义 user/loading/error,methods 里定义 fetchUser,created 里调用 fetchUser——逻辑被撕碎在三处。
组合式 API:将上述所有逻辑封装在 useUser() 一个函数中,相关代码聚集在一起,一目了然。
3. 更好的 TypeScript 支持
组合式 API 基于函数,参数和返回值具有明确的类型,能自动推断组件的状态和方法类型。相比之下,Options API 的类型推断需要额外配置,且容易出错。
4. 更小的生产包体积
组合式 API 对 Tree-shaking 更友好——未使用的组合函数可在构建时被摇树优化移除。这意味着最终打包体积更小。
最佳实践与进阶建议
- 新项目优先使用
<script setup>:这是 Vue 3 官方推荐的组合式 API 编写方式。 - 将可复用逻辑抽取为组合式函数:以 use 开头命名(如 useFetch、usePagination),返回响应式状态和方法。
- 渐进式迁移:新组件用组合式 API,旧组件保留 Options API;逐步将公共逻辑抽成组合式函数。
- 善用 VueUse:不必重复造轮子,VueUse 提供了大量高质量的组合式函数。
- 在 watch 中及时清理副作用:使用 onInvalidate 或在 onUnmounted 中清理定时器、事件监听等。
组合式 API 不仅是 Vue 3 的新特性,更是应对复杂前端应用的必备工具。掌握它,你就掌握了现代 Vue 开发的核心范式。