Skip to content
AskSoul

Vue3 Composition API 完全指南

概述

Vue3 引入了全新的 Composition API,它提供了一种更灵活的方式来组织组件逻辑。本文将深入探讨 Composition API 的设计理念与实践应用。

为什么需要 Composition API?

传统 Options API 的问题

在大型项目中,使用 Options API 可能会导致:

  • 相关逻辑分散在不同的选项中(data、methods、computed)
  • 重用逻辑的机制(mixins)不够清晰
  • TypeScript 支持有限

Composition API 的优势

  1. 更好的逻辑复用 - 通过 composables 函数
  2. 更灵活的代码组织 - 相关逻辑可以放在一起
  3. 更好的 TypeScript 支持 - 天然的 TypeScript 支持
  4. 更小的生产包体积 - 更好的 tree-shaking 支持

核心 API

setup()

setup() 是 Composition API 的入口点,在组件实例创建之前执行。

javascript
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    // 响应式状态
    const count = ref(0)
    const doubled = computed(() => count.value * 2)

    // 方法
    function increment() {
      count.value++
    }

    // 生命周期钩子
    onMounted(() => {
      console.log('Component mounted')
    })

    // 返回暴露给模板
    return {
      count,
      doubled,
      increment
    }
  }
}

响应式系统

ref 和 reactive

javascript
import { ref, reactive, toRefs } from 'vue'

// ref 用于基本类型
const count = ref(0)
console.log(count.value) // 0

// reactive 用于对象
const state = reactive({
  name: 'Vue',
  version: '3.0'
})
console.log(state.name) // Vue

// 解构时使用 toRefs 保持响应性
const { name, version } = toRefs(state)

computed

javascript
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`
})

生命周期钩子

Options APIComposition API
createdsetup()
mountedonMounted
updatedonUpdated
unmountedonUnmounted
javascript
import { onMounted, onUpdated, onUnmounted } from 'vue'

onMounted(() => {
  console.log('Mounted')
})

onUpdated(() => {
  console.log('Updated')
})

onUnmounted(() => {
  console.log('Unmounted')
})

Composables

Compositions API 的真正威力在于组合函数(composables)。

示例:鼠标位置追踪

javascript
// useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(e) {
    x.value = e.clientX
    y.value = e.clientY
  }

  onMounted(() => {
    window.addEventListener('mousemove', update)
  })

  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })

  return { x, y }
}

使用 Composable

javascript
import { useMouse } from './useMouse'

export default {
  setup() {
    const { x, y } = useMouse()

    return { x, y }
  }
}

依赖注入

provide 和 inject

javascript
import { provide, inject } from 'vue'

// 父组件
export default {
  setup() {
    const theme = ref('dark')
    provide('theme', theme)
  }
}

// 子组件
export default {
  setup() {
    const theme = inject('theme')
    return { theme }
  }
}

模板Refs

javascript
import { ref, onMounted } from 'vue'

export default {
  setup() {
    const el = ref(null)

    onMounted(() => {
      console.log(el.value) // DOM 元素
    })

    return { el }
  }
}
html
<template>
  <div ref="el">Hello</div>
</template>

最佳实践

1. 逻辑组织

将相关的逻辑组织在一起,而不是按照选项类型分开。

2. 命名约定

  • Composable 函数以 use 开头
  • 响应式变量使用有意义的名称

3. 性能考虑

  • 避免不必要的响应式转换
  • 合理使用 shallowRefshallowReactive

总结

Vue3 的 Composition API 为我们提供了一种更加灵活和强大的方式来构建 Vue 组件。通过掌握核心 API 和最佳实践,我们可以编写出更加可维护和可测试的代码。