Vue3组合式API精讲:十大核心函数全解析
2025.09.18 18:04浏览量:0简介:本文深入解析Vue3中最常用的10个组合式API,涵盖响应式控制、生命周期、依赖注入等核心功能,通过代码示例和场景说明帮助开发者掌握高效开发技巧。
Vue3组合式API精讲:十大核心函数全解析
Vue3的组合式API(Composition API)是Vue生态中最具变革性的设计之一,它通过逻辑复用和更灵活的代码组织方式,解决了Options API在复杂组件中存在的代码分散问题。本文将系统梳理Vue3中最常用的10个组合式API,结合实际开发场景和代码示例,帮助开发者深入理解其核心价值和使用技巧。
一、响应式控制类API
1. ref:创建响应式引用
ref
是组合式API中最基础的响应式数据创建函数,它接受一个初始值并返回一个具有.value
属性的响应式对象。与Options API中的data
不同,ref
可以用于任何类型的值(包括对象和数组),且通过.value
访问确保响应式追踪。
import { ref } from 'vue'
const count = ref(0) // 初始值为0
function increment() {
count.value++ // 必须通过.value修改
}
适用场景:
- 需要创建独立响应式变量的组件
- 模板中直接使用的简单数据(Vue3模板会自动解包,无需写
.value
) - 与
computed
、watch
等API配合使用
进阶技巧:
对于对象类型,ref
会自动将其内部属性转为响应式(通过reactive
实现),但修改整个对象时仍需使用.value
:
const user = ref({ name: 'Alice' })
user.value.name = 'Bob' // 内部属性响应式
user.value = { name: 'Charlie' } // 必须通过.value替换整个对象
2. reactive:创建深度响应式对象
reactive
用于创建深度响应式的对象,所有嵌套属性都会被自动转换为响应式。与ref
不同,reactive
返回的对象不需要.value
访问,但要求初始值必须是一个对象。
import { reactive } from 'vue'
const state = reactive({
count: 0,
user: { name: 'Alice' }
})
function increment() {
state.count++ // 直接修改
state.user.name = 'Bob' // 嵌套对象自动响应式
}
适用场景:
- 需要管理复杂状态对象的组件
- 状态结构相对稳定的场景(替换整个对象会丢失响应性)
- 与
toRefs
配合解构使用(见下文)
注意事项:
- 不能解构
reactive
对象,否则会失去响应性:const { count } = state // 错误!count不再是响应式
- 使用
toRefs
可以安全解构:import { toRefs } from 'vue'
const { count } = toRefs(state) // count保持响应式
3. computed:创建计算属性
computed
用于创建基于响应式依赖的派生状态,具有缓存机制(只有依赖变化时才会重新计算)。
import { ref, computed } from 'vue'
const num1 = ref(2)
const num2 = ref(3)
const sum = computed(() => num1.value + num2.value)
适用场景:
- 需要基于现有状态派生新状态的场景
- 计算成本较高的操作(如复杂计算或API调用)
- 需要缓存计算结果的场景
进阶用法:
- 可设置getter/setter:
const reversedName = computed({
get: () => name.value.split('').reverse().join(''),
set: (newVal) => {
name.value = newVal.split('').reverse().join('')
}
})
二、生命周期与副作用类API
4. onMounted:组件挂载钩子
onMounted
是组合式API中的生命周期钩子,等价于Options API的mounted
,在组件挂载完成后执行。
import { onMounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('组件已挂载')
// 执行DOM操作或数据初始化
})
}
}
适用场景:
- DOM操作(如获取元素尺寸、初始化第三方库)
- 首次加载时的数据获取
- 订阅外部事件(需配合
onUnmounted
清理)
对比Options API:
组合式API的生命周期钩子可以多次调用,且能更好地组织相关逻辑:
setup() {
// 数据获取逻辑
onMounted(fetchData)
// 初始化图表
onMounted(initChart)
}
5. watch:响应式依赖监听
watch
用于监听响应式数据的变化并执行副作用,支持深度监听和立即执行选项。
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newVal, oldVal) => {
console.log(`count从${oldVal}变为${newVal}`)
})
// 监听多个源
const x = ref(0)
const y = ref(0)
watch([x, y], ([newX, newY], [oldX, oldY]) => {
console.log(`x: ${oldX}→${newX}, y: ${oldY}→${newY}`)
})
适用场景:
- 数据变化时需要执行异步操作(如API调用)
- 需要比较新旧值的场景
- 监听多个相关数据的变化
与watchEffect
对比:watch
需要显式指定监听源,而watchEffect
会自动追踪依赖:
watchEffect(() => {
console.log(`count是${count.value}`) // 自动追踪count
})
6. watchEffect:自动依赖追踪
watchEffect
会在同步执行过程中自动追踪其内部使用的响应式依赖,并在这些依赖变化时重新执行。
import { ref, watchEffect } from 'vue'
const count = ref(0)
const double = ref(0)
watchEffect(() => {
double.value = count.value * 2 // 自动追踪count
})
适用场景:
- 副作用逻辑简单且依赖明确的场景
- 不需要比较新旧值的场景
- 快速原型开发
注意事项:
- 默认会立即执行一次
- 可通过
onInvalidate
注册清理函数:watchEffect((onInvalidate) => {
const timer = setTimeout(() => console.log('延迟执行'), 1000)
onInvalidate(() => clearTimeout(timer)) // 依赖变化时清理
})
三、依赖注入与上下文类API
7. provide/inject:跨组件通信
provide
和inject
实现了祖先组件向后代组件的依赖注入,适用于深层嵌套组件的通信。
// 祖先组件
import { provide, ref } from 'vue'
const theme = ref('dark')
provide('theme', theme)
// 后代组件
import { inject } from 'vue'
const theme = inject('theme', 'light') // 第二个参数是默认值
适用场景:
- 主题切换、用户信息等全局状态
- 复杂组件库的内部通信
- 避免多层
props
传递
响应式处理:
默认情况下,provide
的值是静态的。若需提供响应式值,需直接传递ref
或reactive
对象:
provide('theme', ref('dark')) // 后代组件能响应变化
8. inject:注入依赖
inject
用于在后代组件中获取祖先组件提供的值,支持默认值和强制注入选项。
const user = inject('user', { name: 'Guest' }) // 带默认值
const config = inject('config', undefined, true) // 第三个参数true表示必须提供
最佳实践:
- 对非关键依赖提供合理的默认值
- 关键依赖建议使用
required: true
避免潜在错误 - 结合TypeScript可获得更好的类型提示
四、工具类API
9. toRefs:解构响应式对象
toRefs
将reactive
对象的每个属性转为独立的ref
,保持响应性。
import { reactive, toRefs } from 'vue'
const state = reactive({
count: 0,
name: 'Alice'
})
const { count, name } = toRefs(state) // count和name现在是ref
// 模板中可直接使用count和name(自动解包)
// 脚本中需要.value访问
适用场景:
- 需要解构
reactive
对象但保持响应性 - 函数参数需要响应式对象的部分属性
- 结合TypeScript使用时可获得更好的类型支持
10. nextTick:DOM更新后回调
nextTick
用于在下次DOM更新循环结束之后执行延迟回调,适用于需要基于更新后DOM的操作。
import { ref, nextTick } from 'vue'
const list = ref([])
function addItem() {
list.value.push('new item')
nextTick(() => {
// 此时DOM已更新
console.log(document.getElementById('list').children.length)
})
}
适用场景:
- 需要操作更新后DOM的场景
- 依赖DOM尺寸或位置的逻辑
- 性能优化(避免同步重排)
原理说明:
Vue的DOM更新是异步的,nextTick
利用了JavaScript的事件循环机制,确保在DOM更新后执行回调。
总结与最佳实践
Vue3的组合式API通过逻辑复用和更灵活的代码组织,显著提升了大型应用的开发体验。以下是关键实践建议:
合理选择响应式API:
- 简单值用
ref
,复杂对象用reactive
- 解构时优先使用
toRefs
- 简单值用
生命周期管理:
- 组合式API的生命周期钩子可以多次调用,建议按功能组织
- 记得在
onUnmounted
中清理资源
副作用控制:
- 简单依赖追踪用
watchEffect
- 需要新旧值对比或精确控制时用
watch
- 简单依赖追踪用
状态管理:
- 跨组件状态优先使用
provide/inject
- 复杂应用可考虑Pinia等状态管理库
- 跨组件状态优先使用
性能优化:
- 避免在模板中使用复杂计算,优先使用
computed
- 批量DOM操作配合
nextTick
使用
- 避免在模板中使用复杂计算,优先使用
通过系统掌握这10个核心组合式API,开发者能够更高效地构建可维护、高性能的Vue3应用。组合式API的灵活性不仅简化了代码组织,也为TypeScript集成和逻辑复用提供了更好的支持,是现代Vue开发不可或缺的技能。
发表评论
登录后可评论,请前往 登录 或 注册