本文系统讲解 Vue 3 组合式 API 的核心原理与实战方法,涵盖 语法、ref/reactive 响应式状态、生命周期钩子、逻辑复用 Hook 封装,以及常...
快速概述
Vue 3 组合式 API(Composition API)解决的核心问题是选项式 API(Options API)在复杂组件中逻辑分散、难以复用和维护的痛点。它允许开发者按业务功能而非选项类型组织代码,将相关逻辑封装为可复用的 Hook 函数。适用场景包括中大型单页应用、复杂业务组件以及需要跨组件复用逻辑的场景。前置环境要求:Vue 3.x 项目,推荐搭配 Vite 构建工具,并在单文件组件中使用 <script setup> 语法以获得最简洁的开发体验。
核心概念与原理
组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题。与选项式 API 相比,它不再将代码强制划分为 data、methods、computed 等区块,而是允许你将一个完整的业务模块(如"用户购物车管理")封装成一个 Hook 函数,返回所需的响应式数据和操作方法。实际上,选项式 API 是在组合式 API 的基础上实现的,组合式 API 是更底层、更灵活的设计。在单文件组件中,<script setup> 是一个编译时标识,告诉 Vue 进行特殊处理,让你可以更简洁地使用组合式 API,无需手动导出 setup 函数。
实战步骤与代码
步骤 1:创建 Vue 3 项目
推荐使用 Vite 创建项目,它更轻量且完美支持 TypeScript:
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev
步骤 2:使用 <script setup> 编写基础组件
下面是一个使用组合式 API 的计数器组件,与选项式 API 实现完全相同的功能:
<script setup>
import { ref, onMounted } from 'vue'
// 响应式状态 const count = ref(0)
// 用来修改状态、触发更新的函数 function increment() { count.value++ }
// 生命周期钩子:组件挂载完成后调用 onMounted(() => { console.log(`The initial count is ${count.value}.`) }) </script>
<template> <button @click="increment">Count is: {{ count }}</button> </template>
注意:在 <script setup> 中,ref 创建的响应式变量在模板中会自动解包,无需写 .value,但在 JavaScript 逻辑中必须通过 .value 访问和修改。
步骤 3:封装可复用的 Hook 函数
将购物车管理逻辑封装为 Hook,实现跨组件复用:
// src/composables/useCart.js
import { ref, computed } from 'vue'
// 封装购物车业务模块 export function useCart() { const items = ref([]) const total = computed(() = items.value.reduce((sum, item) => sum + item.price, 0) )
function addItem(item) { items.value.push(item) }
function removeItem(id) { items.value = items.value.filter(item => item.id !== id) }
// 返回响应式数据和操作方法 return { items, total, addItem, removeItem } }
在组件中直接调用 Hook 即可获得完整的购物车逻辑,这正是组合式 API 实现逻辑复用的范式转移。
步骤 4:项目目录结构建议
在实际项目中,建议按以下结构组织代码:
src/views:页面级组件,通常由路由驱动,内部大量使用组合式 API 组织逻辑。src/composables:存放可复用的 Hook 函数。src/store:状态管理,推荐使用 Pinia 替代 Vuex,因其更轻量且完美支持 TypeScript。
这种分层结构让业务逻辑与视图解耦,大幅提升代码可维护性。
常见坑点与优化
坑点 1:忘记 .value
在 JavaScript 逻辑中访问 ref 变量时忘记写 .value,导致状态无法更新或读取到 undefined。建议在开发时开启 ESLint 规则 vue/no-ref-as-operand 来避免此问题。
坑点 2:响应式丢失
使用 reactive 对象时,如果直接解构对象属性,会丢失响应式。解决方案是使用 toRefs 或直接使用 ref 定义基础类型状态。
坑点 3:过度拆分 Hook
不要为了复用而强行拆分 Hook,导致组件逻辑碎片化。建议按业务模块(如购物车、用户认证)而非技术细节拆分。
性能优化建议
- 使用
computed缓存派生状态,避免重复计算。 - 对于大型列表,使用
shallowRef或markRaw减少深层响应式开销。 - 利用
onScopeDispose清理定时器、事件监听器等副作用,防止内存泄漏。
理解 Vue3 的响应式系统底层实现与组合式 API 的设计哲学,是构建高可维护、高性能企业级应用的前提。
评论列表 0