1. 更好的逻辑组织和复用
Options API 的问题
// Options API - 逻辑分散在不同选项中
export default {
data() {
return {
users: [],
loading: false,
searchQuery: '',
pagination: {
page: 1,
limit: 10,
total: 0
}
}
},
computed: {
filteredUsers() {
// 用户筛选逻辑
},
totalPages() {
// 分页计算逻辑
}
},
methods: {
async fetchUsers() {
// 数据获取逻辑
},
handleSearch() {
// 搜索逻辑
},
handlePageChange() {
// 分页逻辑
}
},
mounted() {
this.fetchUsers()
}
}
Composition API 的优势
// Composition API - 按功能组织代码
import { ref, computed, onMounted } from 'vue'
import { userApi } from '@/api/user'
export default {
setup() {
// 用户管理功能
const { users, loading, fetchUsers, searchUsers } = useUserManagement()
// 搜索功能
const { searchQuery, filteredUsers } = useSearch(users)
// 分页功能
const { pagination, paginatedUsers, handlePageChange } = usePagination(filteredUsers)
onMounted(() => {
fetchUsers()
})
return {
users: paginatedUsers,
loading,
searchQuery,
pagination,
handlePageChange,
searchUsers
}
}
}
// 可复用的用户管理逻辑
function useUserManagement() {
const users = ref([])
const loading = ref(false)
const fetchUsers = async () => {
loading.value = true
try {
users.value = await userApi.getUsers()
} finally {
loading.value = false
}
}
const searchUsers = async (query) => {
// 搜索实现
}
return {
users,
loading,
fetchUsers,
searchUsers
}
}
// 可复用的搜索逻辑
function useSearch(source) {
const searchQuery = ref('')
const filteredUsers = computed(() => {
if (!searchQuery.value) return source.value
return source.value.filter(user =>
user.name.includes(searchQuery.value)
)
})
return {
searchQuery,
filteredUsers
}
}
2. 更好的 TypeScript 支持
Composition API 的完整类型推断
import { ref, computed, Ref } from 'vue'
interface User {
id: number
name: string
email: string
role: string
}
// 明确的类型定义
function useUserManagement() {
const users: Ref<User[]> = ref([])
const loading = ref(false)
const adminUsers = computed(() =>
users.value.filter(user => user.role === 'admin')
)
return {
users,
loading,
adminUsers
}
}
3. 更清晰的代码组织模式
基于功能的代码分割
// feature-based-composition.js
export default {
setup() {
// 每个功能独立封装
const cart = useCart()
const user = useUser()
const products = useProducts()
const notifications = useNotifications()
// 功能间的依赖关系更清晰
watch(() => user.isLoggedIn, (loggedIn) => {
if (loggedIn) {
cart.syncCart()
notifications.fetchUnread()
}
})
return {
...cart,
...user,
...products,
...notifications
}
}
}
4. 更好的可测试性
// 独立的逻辑函数易于测试
import { useUserManagement } from './userComposition'
describe('useUserManagement', () => {
it('should fetch users correctly', async () => {
const { users, fetchUsers } = useUserManagement()
await fetchUsers()
expect(users.value).toHaveLength(3)
})
})
5. 解决的具体工程化问题
5.1 逻辑关注点分离
Options API 问题:相关逻辑分散在 data、methods、computed 中
Composition API 解决:相关逻辑集中在一个组合函数中
5.2 代码复用性
Options API 问题:mixins 存在命名冲突和来源不清晰
Composition API 解决:明确的函数调用和返回值
5.3 类型推导
Options API 问题:复杂的 this 上下文类型推断
Composition API 解决:简单的变量和函数类型
5.4 可维护性
Options API 问题:组件越大,代码越难理解和维护
Composition API 解决:按功能拆分为小型、专注的组合函数
5.5 团队协作
// 大型项目中的团队协作示例
export default {
setup() {
// 团队A负责的用户模块
const user = useUserModule()
// 团队B负责的支付模块
const payment = usePaymentModule()
// 团队C负责的通知模块
const notifications = useNotificationModule()
// 清晰的模块边界和接口
return {
...user,
...payment,
...notifications
}
}
}
6.总结
Composition API 在大型项目中更受推荐的主要原因:
- 更好的逻辑组织:按功能而非选项类型组织代码
- 更强的类型支持:完整的 TypeScript 集成
- 更高的复用性:逻辑可以轻松提取和复用
- 更清晰的代码结构:大型组件更易理解和维护
- 更好的可测试性:逻辑与组件实例解耦
- 更佳的团队协作:明确的模块边界和接口