先厘清本质:两种 API 的核心设计差异
很多开发者初学 Vue3 时,仅将 Composition API 当作"新语法",忽略了二者底层设计逻辑的本质区别,这也是无法吃透组合式函数的核心原因。
Options API:按「选项类型」组织代码
Options API 是 Vue2 的经典开发模式,核心逻辑是分类式组织:将组件逻辑按照固定选项拆分,data 存状态、methods 存方法、computed 存计算属性、watch 存监听。
这种模式对新手友好、结构规整,但存在致命工程缺陷:同一业务逻辑被强行拆分到不同选项中。以表单组件为例,表单数据定义、表单校验、提交逻辑、重置逻辑、错误提示属于同一个业务单元,但在 Options API 中会分散在 data、methods、watch 多个区块。
随着组件复杂度提升(如多表单联动、带异步提交、实时校验的业务表单),逻辑碎片化会越来越严重,后续维护需要在多个代码区块之间来回跳转,极易出错。同时,Options API 原生缺乏优雅的逻辑复用方案,依赖 Mixins 实现复用,而 Mixins 存在命名冲突、来源模糊、多混入逻辑嵌套混乱等无法规避的硬伤。
Composition API:按「业务逻辑」组织代码
Composition API 的设计哲学完全反向:抛弃固定选项分类,以业务逻辑单元为核心聚合代码。它允许开发者将一组关联的状态、方法、响应式监听,封装为独立的函数(组合式函数),实现逻辑的内聚、解耦与复用。
其核心设计原则可总结为三点,也是所有 Composables 的设计准则:
逻辑内聚
同一业务的状态、操作、副作用集中管理,不分散在不同选项区块中
状态封装
独立函数维护私有响应式状态,对外暴露可控的状态与方法
灵活复用
无作用域污染、无命名冲突,支持按需引入、组合嵌套
实战落地:表单组件两种 API 开发对比
我们以通用登录表单为实战案例,包含核心业务需求:表单数据双向绑定、实时字段校验、表单重置、提交校验、错误提示、提交加载状态。分别用 Options API 和 Composition API 实现,直观体现差异。
Options API 实现(Vue2 传统写法)
所有逻辑按选项拆分,同一表单业务被拆分多个区块,代码碎片化明显:
export default { data() { return { // 表单状态 form: { username: '', password: '' }, // 错误提示状态 error: { username: '', password: '' }, // 加载状态 loading: false } }, methods: { // 字段校验方法 validateUsername() { if (!this.form.username) { this.error.username = '用户名不能为空' return false } this.error.username = '' return true }, validatePassword() { if (!this.form.password) { this.error.password = '密码不能为空' return false } if (this.form.password.length < 6) { this.error.password = '密码长度不能少于6位' return false } this.error.password = '' return true }, // 表单重置 resetForm() { this.form = { username: '', password: '' } this.error = { username: '', password: '' } }, // 表单提交 async submitForm() { // 统一校验 const nameValid = this.validateUsername() const pwdValid = this.validatePassword() if (!nameValid || !pwdValid) return this.loading = true // 模拟接口提交 await this.$api.login(this.form) this.loading = false alert('提交成功') } } }
该组件仅基础表单逻辑,代码已出现分散问题。若后续新增手机号校验、验证码逻辑、表单联动,对应的状态、校验方法、逻辑处理会继续分散在 data 和 methods 中;且该表单校验、重置逻辑无法复用至注册、修改信息等其他表单组件,只能复制粘贴,冗余度极高。
Composition API 原生实现(未抽离组合函数)
在 setup 函数中按业务聚合逻辑,初步解决碎片化问题,但暂未实现复用:
<script setup> import { ref } from 'vue' // 1. 表单核心状态(业务聚合) const form = ref({ username: '', password: '' }) const error = ref({ username: '', password: '' }) const loading = ref(false) // 2. 字段校验逻辑(和对应状态紧邻) const validateUsername = () => { if (!form.value.username) { error.value.username = '用户名不能为空' return false } error.value.username = '' return true } const validatePassword = () => { if (!form.value.password) { error.value.password = '密码不能为空' return false } if (form.value.password.length < 6) { error.value.password = '密码长度不能少于6位' return false } error.value.password = '' return true } // 3. 表单操作逻辑 const resetForm = () => { form.value = { username: '', password: '' } error.value = { username: '', password: '' } } const submitForm = async () => { if (!validateUsername() || !validatePassword()) return loading.value = true await new Promise(resolve => setTimeout(resolve, 1000)) loading.value = false alert('提交成功') } </script>
相比 Options API,该写法已实现业务逻辑就近聚合,修改表单校验规则时无需跨区块查找代码,但仍存在短板:逻辑封装在组件内部,无法跨组件复用。
核心实战:封装通用表单组合式函数
基于 Composition API 的设计哲学,我们将表单通用校验、重置、状态管理、提交封装抽离为独立组合式函数 useForm,这是 Vue3 标准的逻辑复用模式。组合式函数遵循 use 前缀命名规范,纯函数封装、状态私有化、按需暴露能力。
新建通用组合式函数 composables/useForm.ts
封装通用表单能力,支持自定义校验规则,适配所有表单场景,无业务耦合:
import { ref } from 'vue' // 通用表单组合式函数 export function useForm(initForm = {}, rules = {}) { // 私有化响应式状态 const form = ref({ ...initForm }) const error = ref({}) const loading = ref(false) // 初始化错误对象 const initError = () => { Object.keys(rules).forEach(key => { error.value[key] = '' }) } initError() // 通用字段校验 const validateField = (key: string) => { const rule = rules[key] if (!rule) return true const value = form.value[key] // 必填校验 if (rule.required && !value) { error.value[key] = rule.message return false } // 自定义正则校验 if (rule.pattern && !rule.pattern.test(value)) { error.value[key] = rule.message return false } error.value[key] = '' return true } // 全局表单校验 const validate = () => { let isValid = true Object.keys(rules).forEach(key => { if (!validateField(key)) isValid = false }) return isValid } // 重置表单 const reset = () => { form.value = { ...initForm } initError() } // 通用提交方法 const submit = async (callback: () => Promise<void>) => { if (!validate()) return loading.value = true try { await callback() } finally { loading.value = false } } // 对外暴露状态和方法(按需导出,封装内部逻辑) return { form, error, loading, validateField, validate, reset, submit } }
组件中复用组合式函数
业务组件仅需传入初始化数据和校验规则,无需重复编写通用表单逻辑,极简高效:
<script setup> // 引入通用组合式函数 import { useForm } from '@/composables/useForm' // 传入初始化表单、自定义校验规则,快速生成表单能力 const { form, error, loading, reset, submit } = useForm( // 初始值 { username: '', password: '' }, // 自定义校验规则(业务层配置) { username: { required: true, message: '用户名不能为空' }, password: { required: true, pattern: /^.{6,}$/, message: '密码长度不能少于6位' } } ) // 仅编写业务专属提交逻辑 const handleSubmit = () => { return new Promise((resolve) => { setTimeout(() => { console.log('表单数据:', form.value) resolve() }, 1000) }) } </script> <template> <div class="login-form"> <div> <input v-model="form.username" placeholder="请输入用户名" /> <p class="error">{{ error.username }}</p> </div> <div> <input v-model="form.password" type="password" placeholder="请输入密码" /> <p class="error">{{ error.password }}</p> </div> <button @click="submit(handleSubmit)" :disabled="loading"> {{ loading ? '提交中...' : '登录' }} </button> <button @click="reset">重置</button> </div> </template>
深度拆解:组合式函数的设计哲学与核心优势
通过上述实战案例,我们可以实事求是总结 Composition API 与 Composables 的核心设计思想,以及相对 Options API 的本质优势,摒弃网络夸大化宣传,聚焦真实工程价值。
逻辑高内聚,彻底解决代码碎片化
Options API 的致命缺陷是逻辑与结构绑定,业务逻辑被语法结构拆分;而组合式函数以业务领域为单元,将状态、校验、操作、副作用完整封装,同一逻辑闭环内聚管理。复杂组件中,可拆分 useForm、useTable、usePagination、useRequest 等多个组合函数,代码结构清晰、职责单一。
纯粹可靠的逻辑复用,规避 Mixins 所有缺陷
Vue2 复用逻辑依赖 Mixins,存在三大不可解决的问题:隐式依赖、命名冲突、多混入逻辑混乱。而组合式函数的复用模式完全透明:显式输入输出、零命名冲突、支持参数定制。本文封装的 useForm 函数,可直接复用在登录、注册、个人信息编辑、商品录入等所有表单场景。
分层解耦,适配大型项目工程化架构
组合式函数天然支持分层设计:基础层提供通用 composable,业务层封装业务组合函数,组件层专注视图渲染。这种分层模式彻底实现视图、逻辑、业务、底层能力的解耦,极大降低大型项目的维护成本。
完美适配 TypeScript,类型推导更精准
Options API 基于对象配置,TS 类型推导存在局限性,复杂场景需要额外类型声明;而组合式函数基于纯函数实现,天然适配 TS,入参、出参可精准定义类型,实现完整的类型约束和智能提示,大幅减少线上 bug。
按需引入,打包体积更轻量化
Options API 所有选项都会被挂载到组件实例,无论是否使用;组合式函数支持按需导入、按需使用,未调用的逻辑不会执行,配合 tree-shaking 可有效减少冗余代码,优化打包体积。这对中大型项目的性能优化具有实质性的工程价值。
基础层(useForm、useRequest、usePagination)→ 无业务耦合,全局通用 | 业务层(useLoginForm、useUserForm)→ 适配专属业务场景 | 组件层 → 仅调用业务组合函数,专注视图渲染
客观认知:Composition API 并非万能
本着实事求是、不弄虚作假的原则,必须客观说明:Composition API 是增强方案而非替代方案。
简单组件优先 Options API
对于纯展示、无复杂逻辑、无复用需求的简单组件,Options API 代码更简洁、上手更快,无需强行使用组合式函数。
复杂场景适用 Composition API
对于复杂业务组件、多逻辑嵌套、需要跨组件复用、长期迭代维护的场景,Composition API + Composables 才有绝对优势。
Vue3 官方也明确支持两种 API 共存,最佳实践是:简单场景用 Options API 高效开发,复杂场景用 Composition API 规范架构。技术选型应基于实际场景需求,而非盲目追新。
总结:组合式函数的核心设计哲学
通过完整表单案例的实战对比,可最终凝练出 Vue3 Composition API 组合式函数的核心设计哲学: