Skip to content

组合式 API 介绍

组合式 API(Composition API)是Vue3中引入的一个重要特性,它允许你根据功能组织代码,而不是根据选项类型。本章节将详细介绍Vue3中组合式API的基本概念和使用方法。

什么是组合式 API?

组合式 API 是Vue3中一种新的API风格,它允许你使用函数而不是选项来组织组件的逻辑。通过组合式API,你可以将相关的逻辑组合在一起,提高代码的可维护性和可复用性。

组合式 API 的优势

1. 更好的代码组织

组合式API允许你根据功能组织代码,而不是根据选项类型。这使得代码更加清晰,易于理解和维护。

2. 更好的类型推导

组合式API提供了更好的TypeScript支持,类型推导更加准确。

3. 更好的代码复用

通过组合式API,你可以创建可复用的逻辑函数,这些函数可以在多个组件中使用。

4. 更好的代码可读性

组合式API使得代码的逻辑流程更加清晰,易于理解。

组合式 API 与选项式 API 的对比

选项式 API

vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
    <button @click="increment">Increment</button>
    <p>Count: {{ count }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'Hello Vue3!',
      message: 'Welcome to Vue3',
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  mounted() {
    console.log('Component mounted')
  }
}
</script>

组合式 API

vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
    <button @click="increment">Increment</button>
    <p>Count: {{ count }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const title = ref('Hello Vue3!')
const message = ref('Welcome to Vue3')
const count = ref(0)

const increment = () => {
  count.value++
}

onMounted(() => {
  console.log('Component mounted')
})
</script>

组合式 API 的基本使用

1. setup 函数

在Vue3中,你可以使用setup函数来使用组合式API:

vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const title = ref('Hello Vue3!')
    const message = ref('Welcome to Vue3')
    
    return {
      title,
      message
    }
  }
}
</script>

2. setup 语法糖

在Vue3.2+中,你可以使用setup语法糖来简化代码:

vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
  </div>
</template>

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

const title = ref('Hello Vue3!')
const message = ref('Welcome to Vue3')
</script>

组合式 API 的核心概念

1. 响应式 API

组合式API提供了一系列用于创建响应式数据的函数:

  • ref:创建响应式的基本类型数据
  • reactive:创建响应式的对象或数组
  • toRef:创建指向响应式对象属性的引用
  • toRefs:将响应式对象的所有属性转换为引用
  • computed:创建计算属性
  • watch:监听响应式数据的变化
  • watchEffect:自动追踪响应式数据的变化

2. 生命周期钩子

组合式API提供了一系列生命周期钩子:

  • onMounted:组件挂载后执行
  • onUpdated:组件更新后执行
  • onUnmounted:组件卸载后执行
  • onBeforeMount:组件挂载前执行
  • onBeforeUpdate:组件更新前执行
  • onBeforeUnmount:组件卸载前执行

3. 依赖注入

组合式API提供了依赖注入的功能:

  • provide:提供数据给后代组件
  • inject:从祖先组件注入数据

组合式 API 的使用场景

1. 复杂组件

对于逻辑复杂的组件,组合式API可以使代码更加清晰:

vue
<template>
  <div class="user-profile">
    <h1>{{ user.name }}</h1>
    <p>{{ user.email }}</p>
    <button @click="fetchUser">Refresh User</button>
    <div v-if="loading">Loading...</div>
    <div v-else-if="error">{{ error }}</div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// 用户数据相关逻辑
const user = ref({})
const loading = ref(false)
const error = ref('')

const fetchUser = async () => {
  loading.value = true
  error.value = ''
  try {
    const response = await fetch('https://api.example.com/user')
    if (!response.ok) {
      throw new Error('Failed to fetch user')
    }
    const data = await response.json()
    user.value = data
  } catch (err) {
    error.value = err.message
  } finally {
    loading.value = false
  }
}

// 生命周期钩子
onMounted(() => {
  fetchUser()
})
</script>

2. 可复用逻辑

通过组合式API,你可以创建可复用的逻辑函数:

javascript
// composables/useCounter.js
import { ref, computed } from 'vue'

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

然后在组件中使用:

vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

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

const { count, doubleCount, increment, decrement } = useCounter(0)
</script>

3. 多个逻辑关注点

对于有多个逻辑关注点的组件,组合式API可以使代码更加清晰:

vue
<template>
  <div class="dashboard">
    <h1>Dashboard</h1>
    <div class="stats">
      <div class="stat">
        <h2>Users</h2>
        <p>{{ userCount }}</p>
      </div>
      <div class="stat">
        <h2>Posts</h2>
        <p>{{ postCount }}</p>
      </div>
      <div class="stat">
        <h2>Comments</h2>
        <p>{{ commentCount }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// 用户数据逻辑
const userCount = ref(0)
const fetchUsers = async () => {
  const response = await fetch('https://api.example.com/users')
  const data = await response.json()
  userCount.value = data.length
}

// 帖子数据逻辑
const postCount = ref(0)
const fetchPosts = async () => {
  const response = await fetch('https://api.example.com/posts')
  const data = await response.json()
  postCount.value = data.length
}

// 评论数据逻辑
const commentCount = ref(0)
const fetchComments = async () => {
  const response = await fetch('https://api.example.com/comments')
  const data = await response.json()
  commentCount.value = data.length
}

// 生命周期钩子
onMounted(async () => {
  await fetchUsers()
  await fetchPosts()
  await fetchComments()
})
</script>

组合式 API 的最佳实践

1. 按功能组织代码

使用组合式API时,应该按功能组织代码,将相关的逻辑放在一起:

javascript
// 好的做法:按功能组织代码
const user = ref({})
const loading = ref(false)
const error = ref('')

const fetchUser = async () => {
  // 逻辑代码
}

onMounted(() => {
  fetchUser()
})

// 不好的做法:按API类型组织代码
const user = ref({})
const loading = ref(false)
const error = ref('')

onMounted(() => {
  fetchUser()
})

const fetchUser = async () => {
  // 逻辑代码
}

2. 创建可复用的 composables

对于可复用的逻辑,应该创建独立的 composables:

javascript
// composables/useApi.js
import { ref } from 'vue'

export function useApi(url) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref('')
  
  const fetchData = async () => {
    loading.value = true
    error.value = ''
    try {
      const response = await fetch(url)
      if (!response.ok) {
        throw new Error('Failed to fetch data')
      }
      data.value = await response.json()
    } catch (err) {
      error.value = err.message
    } finally {
      loading.value = false
    }
  }
  
  return {
    data,
    loading,
    error,
    fetchData
  }
}

3. 合理使用响应式 API

根据数据类型选择合适的响应式API:

  • ref:用于基本类型数据
  • reactive:用于对象或数组
  • computed:用于计算属性
  • watch:用于监听数据变化

4. 避免在模板中使用复杂表达式

模板中的表达式应该简单明了,复杂逻辑应该放在组合式API中:

vue
<!-- 好的做法 -->
<template>
  <div>
    <p>{{ formattedPrice }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const price = ref(199.99)
const formattedPrice = computed(() => {
  return `$${price.value.toFixed(2)}`
})
</script>

<!-- 不好的做法 -->
<template>
  <div>
    <p>{{ `$${price.toFixed(2)}` }}</p>
  </div>
</template>

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

const price = ref(199.99)
</script>

总结

组合式API是Vue3中一个重要的特性,它允许你根据功能组织代码,提高代码的可维护性和可复用性。通过组合式API,你可以创建更加清晰、可维护的组件。

在使用组合式API时,你应该按功能组织代码,创建可复用的composables,合理使用响应式API,以及避免在模板中使用复杂表达式。

在后续的章节中,我们将学习Vue3的setup语法糖、响应式API等内容。

© 2026 编程马·菜鸟教程 版权所有