Vue3组合式API核心指南:掌握10个关键函数

Vue3组合式API核心指南:掌握10个关键函数

Vue3的组合式API(Composition API)通过逻辑复用与响应式编程重构了组件开发范式。相较于Options API的分散式配置,组合式API将相关逻辑集中管理,尤其适合中大型项目的状态共享与复杂交互场景。本文精选10个高频使用的组合式函数,从基础响应式到高级生命周期控制,结合实战案例解析其核心价值。

一、响应式基础:reactive与ref

1. reactive:深度响应式对象

reactive()将普通对象转换为响应式代理,适用于嵌套结构的状态管理。其核心特性包括:

  • 深度监听:自动追踪对象内部所有层级的属性变化
  • 不可解构:直接解构会丢失响应性(需配合toRefs使用)
    1. import { reactive, toRefs } from 'vue'
    2. const state = reactive({
    3. user: { name: 'Alice', age: 25 },
    4. items: []
    5. })
    6. // 保持响应式的解构方式
    7. const { user } = toRefs(state)

    最佳实践:用于管理组件级共享状态,如表单数据、列表项等。避免对原始值(如字符串、数字)使用,此时应优先选择ref

2. ref:通用响应式容器

ref()通过.value属性包装任意类型值,解决原始值响应式问题:

  • 自动解包:在模板中可直接使用,无需.value
  • 类型安全:配合TypeScript可精确约束值类型
    1. import { ref } from 'vue'
    2. const count = ref(0) // 实际存储为 { value: 0 }
    3. const inputRef = ref<HTMLInputElement | null>(null)

    性能优化:对大型数组或对象,优先使用reactive()减少包装开销;对可能变化的类型(如从API获取的数据),ref的显式赋值更安全。

二、计算与监听:computed与watch

3. computed:惰性派生状态

computed()创建缓存的计算属性,仅在依赖变化时重新计算:

  • 惰性求值:首次访问时触发计算,后续读取缓存值
  • 响应式依赖:自动追踪内部使用的响应式变量
    1. import { computed, ref } from 'vue'
    2. const a = ref(1)
    3. const b = ref(2)
    4. const sum = computed(() => a.value + b.value)

    适用场景:频繁读取但计算成本较高的派生数据,如过滤后的列表、格式化显示文本等。

4. watch:异步副作用监听

watch()监听响应式变化并执行异步操作,支持深度监听与立即触发:

  • 深度监听{ deep: true }可监听对象内部变化
  • 立即执行{ immediate: true }在初始化时触发回调
    1. import { watch, ref } from 'vue'
    2. const query = ref('')
    3. watch(query, (newVal, oldVal) => {
    4. if (newVal.length > 3) {
    5. fetchData(newVal) // 防抖处理建议在此处添加
    6. }
    7. }, { immediate: true })

    进阶技巧:监听多个源时使用数组watch([a, b], callback);对复杂对象建议监听特定属性而非整个对象。

三、生命周期与上下文:onMounted与provide/inject

5. onMounted:DOM就绪钩子

onMounted()在组件挂载后执行,替代Options API的mounted

  • 执行时机:确保DOM已渲染,可安全操作元素
  • 组合式优势:可与异步操作结合,如数据加载
    1. import { onMounted, ref } from 'vue'
    2. const data = ref(null)
    3. onMounted(async () => {
    4. data.value = await fetch('/api/data')
    5. })

    注意事项:避免在此钩子中修改可能触发重新渲染的状态,可能导致无限循环。

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’)

  1. **适用场景**:主题配置、用户权限、全局配置等跨多层级组件共享的状态。
  2. ## 四、高级工具函数:自定义hook与性能优化
  3. ### 7. 自定义Hook:逻辑复用
  4. 通过组合基础API封装可复用逻辑,如分页控制、表单验证:
  5. ```javascript
  6. // usePagination.js
  7. import { ref, computed } from 'vue'
  8. export function usePagination(total, pageSize = 10) {
  9. const currentPage = ref(1)
  10. const paginatedData = computed(() => {
  11. const start = (currentPage.value - 1) * pageSize
  12. return total.slice(start, start + pageSize)
  13. })
  14. return { currentPage, paginatedData }
  15. }

设计原则:单一职责、明确输入输出、避免副作用。

8. watchEffect:自动追踪依赖

watchEffect()自动追踪回调内使用的响应式依赖,简化监听逻辑:

  • 自动清理:组件卸载时自动停止副作用
  • 无初始执行:首次运行在组件设置后
    1. import { watchEffect, ref } from 'vue'
    2. const pos = ref({ x: 0, y: 0 })
    3. watchEffect(() => {
    4. console.log(`Position: ${pos.value.x}, ${pos.value.y}`)
    5. })

    对比watch:适合依赖关系动态变化的场景,但无法获取旧值。

五、实用工具:模板引用与异步控制

9. template refs:DOM元素访问

通过ref()获取模板中元素的引用,替代this.$refs

  • 类型安全:可指定具体元素类型
  • 组合式集成:与生命周期钩子配合实现初始化逻辑
    ```javascript
    // 模板@input="handleInput" />

// 脚本
import { ref, onMounted } from ‘vue’
const inputRef = ref(null)
onMounted(() => {
inputRef.value?.focus()
})

  1. ### 10. Suspense:异步组件加载
  2. `Suspense`组件与异步setup配合,实现组件级加载状态管理:
  3. - **fallback**:指定加载中的备用内容
  4. - **延迟加载**:结合`defineAsyncComponent`优化首屏性能
  5. ```javascript
  6. // 异步组件
  7. const AsyncComponent = defineAsyncComponent(() =>
  8. import('./HeavyComponent.vue')
  9. )
  10. // 父组件模板
  11. <Suspense>
  12. <template #default>
  13. <AsyncComponent />
  14. </template>
  15. <template #fallback>
  16. <div>Loading...</div>
  17. </template>
  18. </Suspense>

总结与最佳实践

  1. 响应式选择:对象用reactive(),原始值用ref(),大型数据结构优先考虑性能
  2. 计算属性优化:将复杂计算移至computed(),避免模板中直接处理逻辑
  3. 监听解耦:使用watchEffect处理动态依赖,watch处理明确依赖
  4. 状态共享:跨层级状态优先provide/inject,避免过度使用全局状态管理库
  5. 类型安全:为所有refreactive添加TypeScript类型约束

通过系统掌握这10个核心API,开发者可构建出更清晰、可维护的Vue3应用。在实际项目中,建议结合具体业务场景进行组合创新,例如将自定义Hook与状态管理结合,或利用Suspense优化复杂路由的加载体验。