Appearance
组合式 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等内容。
