Vue 3 Composition API 完全指南从入门到企业级实践
Vue 3的Composition API是Vue生态系统的一次重大革新,它提供了更灵活的代码组织方式和更强大的逻辑复用能力。本文从基础概念出发,深入讲解setup函数、响应式API、计算属性、侦听器等核心特性,并结合企业级项目实战案例,帮助开发者掌握Composition API的最佳实践。
# Vue 3 Composition API 完全指南:从入门到企业级实践
## 前言
Vue 3 自发布以来,其最引人注目的特性莫过于 Composition API(组合式 API)。作为 Vue 2 Options API 的重要补充,Composition API 提供了更灵活的代码组织方式,特别适合大型项目的开发场景。本文将深入探讨 Composition API 的核心概念、使用方法以及企业级最佳实践。
## 什么是 Composition API
Composition API 是一组基于函数的 API,允许开发者更灵活地组织组件逻辑。与 Options API 按选项类型(data、methods、computed 等)组织代码不同,Composition API 允许按功能逻辑组织代码,使得相关代码能够放在一起,大幅提升代码的可读性和可维护性。
### 为什么需要 Composition API
在 Vue 2 的 Options API 中,随着组件复杂度增加,相关逻辑会被拆分到不同选项中,导致代码散落各处,难以维护。Composition API 通过将相关逻辑聚合在一起,解决了这一问题。
主要优势包括:
1. **更好的逻辑复用**:通过组合式函数(Composables)实现跨组件逻辑复用
2. **更灵活的代码组织**:按功能而非选项类型组织代码
3. **更好的 TypeScript 支持**:原生 TypeScript 支持,类型推断更准确
4. **更小的打包体积**:更好的 tree-shaking 支持
## setup 函数详解
setup 函数是 Composition API 的入口,它在组件创建之前执行,返回的对象会暴露给模板和组件实例。
```javascript
import { ref, computed } from 'vue'
export default {
setup() {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return {
count,
doubleCount,
increment
}
}
}
```
### setup 函数的参数
setup 函数接收两个参数:
1. **props**:组件接收的属性(响应式)
2. **context**:上下文对象,包含 attrs、slots、emit
```javascript
setup(props, context) {
// props 是响应式的
console.log(props.title)
// context 包含 attrs、slots、emit
context.emit('update', newValue)
}
```
## 响应式核心 API
### ref 和 reactive
Vue 3 提供了两种创建响应式数据的方式:
**ref**:适用于基本类型值和需要重新赋值的引用类型
```javascript
import { ref } from 'vue'
const count = ref(0) // 访问/修改需要通过 .value
console.log(count.value) // 0
count.value++
```
**reactive**:适用于对象类型,返回对象的响应式代理
```javascript
import { reactive } from 'vue'
const state = reactive({ count: 0, name: 'Vue' })
state.count++ // 直接访问,无需 .value
```
### 选择 ref 还是 reactive
- 使用 **ref**:当你需要重新赋值整个对象,或者值是基本类型
- 使用 **reactive**:当你有一个对象且不需要重新赋值时
实际上,许多开发者倾向于统一使用 ref,因为它更一致,且在组合式函数中返回 ref 更符合预期。
## 计算属性与侦听器
### computed
computed 创建响应式计算值,具有缓存机制:
```javascript
import { ref, computed } from 'vue'
const price = ref(10)
const quantity = ref(2)
const total = computed(() => price.value * quantity.value)
```
也可以创建可写的计算属性:
```javascript
const firstName = ref('Zhang')
const lastName = ref('San')
const fullName = computed({
get() {
return firstName.value + ' ' + lastName.value
},
set(newValue) {
const [first, last] = newValue.split(' ')
firstName.value = first
lastName.value = last || ''
}
})
```
### watch 和 watchEffect
**watch**:显式指定要侦听的数据源
```javascript
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newVal, oldVal) => {
console.log(`count changed: ${oldVal} -> ${newVal}`)
})
```
**watchEffect**:立即执行并自动追踪依赖
```javascript
import { ref, watchEffect } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
watchEffect(() => {
console.log(`count: ${count.value}, doubled: ${doubled.value}`)
})
```
## 组合式函数(Composables)
组合式函数是 Composition API 最强大的特性之一,它允许将组件逻辑提取到可复用的函数中。
### 创建组合式函数
```javascript
// 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: ref,
increment,
decrement,
reset
}
}
```
### 在组件中使用
```javascript
import { useCounter } from './useCounter'
export default {
setup() {
const { count, increment, decrement, reset } = useCounter(10)
return {
count,
increment,
decrement,
reset
}
}
}
```
## 生命周期钩子
Composition API 提供了一组 onXXX 函数来注册生命周期钩子:
```javascript
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('组件已挂载')
})
onUpdated(() => {
console.log('组件已更新')
})
onUnmounted(() => {
console.log('组件已卸载')
})
}
}
```
## 模板引用(Template Refs)
在 Composition API 中获取模板引用:
```javascript
import { ref, onMounted } from 'vue'
export default {
setup() {
const inputRef = ref(null)
onMounted(() => {
inputRef.value.focus()
})
return {
inputRef
}
}
}
```
模板中:
```html
<input ref="inputRef" />
```
## 企业级最佳实践
### 1. 合理拆分组合式函数
将复杂逻辑拆分成小的、单一职责的组合式函数,每个函数只做一件事。
### 2. 使用 TypeScript 增强类型安全
```typescript
import { ref } from 'vue'
interface User {
id: number
name: string
email: string
}
export function useUser() {
const user = ref<User | null>(null)
function setUser(newUser: User) {
user.value = newUser
}
return {
user,
setUser
}
}
```
### 3. 避免常见的响应式陷阱
- 解构响应式对象会失去响应性,使用 `toRefs` 保持响应性
- 在 `watch` 中侦听响应式对象时,需要深度侦听或使用 getter 函数
- 异步更新状态时注意 `await` 的时机
### 4. 合理选择 API 风格
- 小型组件:Options API 更简洁
- 大型组件/逻辑复用:Composition API 更合适
- 两者可以混合使用,不必非此即彼
## 总结
Vue 3 的 Composition API 为开发者提供了更强大、更灵活的工具来构建复杂的应用程序。通过本文的学习,你应该已经掌握了 setup 函数、响应式 API、计算属性、侦听器、组合式函数等核心概念,并了解了企业级开发中的最佳实践。
在实际项目中,建议逐步迁移到 Composition API,先从新的组件开始使用,积累经验后再考虑重构现有组件。同时,充分利用组合式函数实现逻辑复用,提升代码的可维护性和可测试性。
Vue 3 的生态正在不断完善,Composition API 也将继续演进。保持学习,跟上官方文档的更新,才能充分发挥 Vue 3 的潜力。