Vue3组合式API核心指南:掌握10个关键函数
Vue3的组合式API(Composition API)通过逻辑复用与响应式编程重构了组件开发范式。相较于Options API的分散式配置,组合式API将相关逻辑集中管理,尤其适合中大型项目的状态共享与复杂交互场景。本文精选10个高频使用的组合式函数,从基础响应式到高级生命周期控制,结合实战案例解析其核心价值。
一、响应式基础:reactive与ref
1. reactive:深度响应式对象
reactive()将普通对象转换为响应式代理,适用于嵌套结构的状态管理。其核心特性包括:
- 深度监听:自动追踪对象内部所有层级的属性变化
- 不可解构:直接解构会丢失响应性(需配合
toRefs使用)import { reactive, toRefs } from 'vue'const state = reactive({user: { name: 'Alice', age: 25 },items: []})// 保持响应式的解构方式const { user } = toRefs(state)
最佳实践:用于管理组件级共享状态,如表单数据、列表项等。避免对原始值(如字符串、数字)使用,此时应优先选择
ref。
2. ref:通用响应式容器
ref()通过.value属性包装任意类型值,解决原始值响应式问题:
- 自动解包:在模板中可直接使用,无需
.value - 类型安全:配合TypeScript可精确约束值类型
import { ref } from 'vue'const count = ref(0) // 实际存储为 { value: 0 }const inputRef = ref<HTMLInputElement | null>(null)
性能优化:对大型数组或对象,优先使用
reactive()减少包装开销;对可能变化的类型(如从API获取的数据),ref的显式赋值更安全。
二、计算与监听:computed与watch
3. computed:惰性派生状态
computed()创建缓存的计算属性,仅在依赖变化时重新计算:
- 惰性求值:首次访问时触发计算,后续读取缓存值
- 响应式依赖:自动追踪内部使用的响应式变量
import { computed, ref } from 'vue'const a = ref(1)const b = ref(2)const sum = computed(() => a.value + b.value)
适用场景:频繁读取但计算成本较高的派生数据,如过滤后的列表、格式化显示文本等。
4. watch:异步副作用监听
watch()监听响应式变化并执行异步操作,支持深度监听与立即触发:
- 深度监听:
{ deep: true }可监听对象内部变化 - 立即执行:
{ immediate: true }在初始化时触发回调import { watch, ref } from 'vue'const query = ref('')watch(query, (newVal, oldVal) => {if (newVal.length > 3) {fetchData(newVal) // 防抖处理建议在此处添加}}, { immediate: true })
进阶技巧:监听多个源时使用数组
watch([a, b], callback);对复杂对象建议监听特定属性而非整个对象。
三、生命周期与上下文:onMounted与provide/inject
5. onMounted:DOM就绪钩子
onMounted()在组件挂载后执行,替代Options API的mounted:
- 执行时机:确保DOM已渲染,可安全操作元素
- 组合式优势:可与异步操作结合,如数据加载
import { onMounted, ref } from 'vue'const data = ref(null)onMounted(async () => {data.value = await fetch('/api/data')})
注意事项:避免在此钩子中修改可能触发重新渲染的状态,可能导致无限循环。
6. provide/inject:跨层级状态传递
provide()与inject()实现祖先组件向后代组件传递数据,避免层层props传递:
- 响应式传递:使用
reactive()或ref()包装数据保持响应性 - 键名约定:建议使用Symbol作为键避免命名冲突
```javascript
// 祖先组件
import { provide, reactive } from ‘vue’
const theme = reactive({ color: ‘blue’ })
provide(‘theme’, theme)
// 后代组件
import { inject } from ‘vue’
const theme = inject(‘theme’)
**适用场景**:主题配置、用户权限、全局配置等跨多层级组件共享的状态。## 四、高级工具函数:自定义hook与性能优化### 7. 自定义Hook:逻辑复用通过组合基础API封装可复用逻辑,如分页控制、表单验证:```javascript// usePagination.jsimport { ref, computed } from 'vue'export function usePagination(total, pageSize = 10) {const currentPage = ref(1)const paginatedData = computed(() => {const start = (currentPage.value - 1) * pageSizereturn total.slice(start, start + pageSize)})return { currentPage, paginatedData }}
设计原则:单一职责、明确输入输出、避免副作用。
8. watchEffect:自动追踪依赖
watchEffect()自动追踪回调内使用的响应式依赖,简化监听逻辑:
- 自动清理:组件卸载时自动停止副作用
- 无初始执行:首次运行在组件设置后
import { watchEffect, ref } from 'vue'const pos = ref({ x: 0, y: 0 })watchEffect(() => {console.log(`Position: ${pos.value.x}, ${pos.value.y}`)})
对比watch:适合依赖关系动态变化的场景,但无法获取旧值。
五、实用工具:模板引用与异步控制
9. template refs:DOM元素访问
通过ref()获取模板中元素的引用,替代this.$refs:
- 类型安全:可指定具体元素类型
- 组合式集成:与生命周期钩子配合实现初始化逻辑
```javascript
// 模板@input="handleInput" />
// 脚本
import { ref, onMounted } from ‘vue’
const inputRef = ref(null)
onMounted(() => {
inputRef.value?.focus()
})
### 10. Suspense:异步组件加载`Suspense`组件与异步setup配合,实现组件级加载状态管理:- **fallback**:指定加载中的备用内容- **延迟加载**:结合`defineAsyncComponent`优化首屏性能```javascript// 异步组件const AsyncComponent = defineAsyncComponent(() =>import('./HeavyComponent.vue'))// 父组件模板<Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
总结与最佳实践
- 响应式选择:对象用
reactive(),原始值用ref(),大型数据结构优先考虑性能 - 计算属性优化:将复杂计算移至
computed(),避免模板中直接处理逻辑 - 监听解耦:使用
watchEffect处理动态依赖,watch处理明确依赖 - 状态共享:跨层级状态优先
provide/inject,避免过度使用全局状态管理库 - 类型安全:为所有
ref和reactive添加TypeScript类型约束
通过系统掌握这10个核心API,开发者可构建出更清晰、可维护的Vue3应用。在实际项目中,建议结合具体业务场景进行组合创新,例如将自定义Hook与状态管理结合,或利用Suspense优化复杂路由的加载体验。