Skip to content

Vue 3 组合式 API 完全指南

组合式 API (Composition API) 是 Vue 3 引入的全新 API 风格,让代码组织更加灵活。

为什么需要组合式 API?

逻辑复用

相比 Mixins,组合式 API 提供了更好的代码组织方式:

typescript
// useCounter.ts
import { ref, computed } from 'vue';

export function useCounter() {
  const count = ref(0);
  
  const double = computed(() => count.value * 2);
  
  const increment = () => count.value++;
  const decrement = () => count.value--;
  const reset = () => count.value = 0;
  
  return {
    count,
    double,
    increment,
    decrement,
    reset
  };
}

使用:

vue
<script setup>
import { useCounter } from './useCounter';

const { count, double, increment, decrement } = useCounter();
</script>

响应式基础

ref 和 reactive

typescript
import { ref, reactive } from 'vue';

// ref - 用于原始类型
const count = ref(0);
console.log(count.value); // 0

// reactive - 用于对象
const state = reactive({
  name: 'Alice',
  age: 25
});
console.log(state.name); // Alice

computed

typescript
import { ref, computed } from 'vue';

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

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

watch 和 watchEffect

typescript
import { ref, watch, watchEffect } from 'vue';

const count = ref(0);

// 监视特定数据
watch(count, (newValue, oldValue) => {
  console.log(`count changed: ${oldValue} -> ${newValue}`);
});

// 立即执行,自动追踪依赖
watchEffect(() => {
  console.log(`count is: ${count.value}`);
});

生命周期钩子

vue
<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue';

onMounted(() => {
  console.log('Component mounted');
});

onUpdated(() => {
  console.log('Component updated');
});

onUnmounted(() => {
  console.log('Component unmounted');
});
</script>

常用钩子对照:

选项式 API组合式 API
created-
mountedonMounted
updatedonUpdated
unmountedonUnmounted
beforeCreate-
beforeMountonBeforeMount
beforeUpdateonBeforeUpdate
beforeUnmountonBeforeUnmount

依赖注入

typescript
import { inject, provide } from 'vue';

// 父组件
import { ref } from 'vue';

const theme = ref('dark');
provide('theme', theme);

// 子组件
const theme = inject('theme');

模板引用

vue
<script setup>
import { ref } from 'vue';

const inputRef = ref<HTMLInputElement | null>(null);

const focusInput = () => {
  inputRef.value?.focus();
};
</script>

<template>
  <input ref="inputRef" type="text" />
  <button @click="focusInput">Focus</button>
</template>

与 TypeScript 结合

vue
<script setup lang="ts">
interface User {
  name: string;
  age: number;
}

const user = ref<User | null>(null);

const fetchUser = async (id: number): Promise<void> => {
  const response = await fetch(`/api/users/${id}`);
  user.value = await response.json();
};
</script>

最佳实践

  1. 使用 <script setup> - 更简洁的语法
  2. 类型推导 - 让 TypeScript 自动推导类型
  3. 组合式函数 - 将相关逻辑封装为可复用的函数
  4. 响应式解构 - 使用 toRefs 保持响应性

总结

组合式 API 提供了更灵活的代码组织方式,特别适合复杂组件和逻辑复用。建议在新项目中使用 Vue 3 + 组合式 API + TypeScript 的组合。


标签: Vue TypeScript

基于 VitePress 构建