Vue3 Composition API 完全指南
📚 目录
- 组合式API核心概念
 - 与选项式API对比
 - setup深度解析
 - 响应式API体系
 - 生命周期管理
 - 逻辑复用模式
 - 最佳实践
 
🌟 组合式API核心概念
定义
组合式API(Composition API)是Vue3的核心特性,它通过逻辑功能聚合和高复用性解决了复杂组件的代码组织问题。主要特征:
- 功能聚合:将同一功能的响应式数据、计算属性、方法等集中管理
 - 逻辑复用:通过自定义Hook实现跨组件逻辑复用
 - 类型支持:完美支持TypeScript类型推断
 - 渐进式:可与选项式API混合使用
 
组合式api解决了什么问题
通过组合式api,将代码封装成为功能模块,并且在组件之间共享,实现逻辑代码的复用。
| 问题类型 | 选项式API痛点 | 组合式API解决方案 | 
|---|---|---|
| 代码组织 | 功能分散在多个配置项 | 按功能聚合逻辑 | 
| 大型组件维护 | 超过1000行代码难以维护 | 拆分为多个逻辑单元 | 
| 逻辑复用 | Mixins导致命名冲突 | 可组合函数 | 
| TypeScript支持 | 类型推断困难 | 天然支持类型推导 | 
🔧 setup深度解析
基础用法
// 传统写法
export default {setup(props, context) {const count = ref(0)const double = computed(() => count.value * 2)function increment() {count.value++}return { count,double,increment}}
}// <script setup> 语法糖(推荐)
<script setup>
import { ref, computed } from 'vue'const count = ref(0)
const double = computed(() => count.value * 2)function increment() {count.value++
}
</script>
 
生命周期映射表
| 选项式API | 组合式API | 执行时机 | 
|---|---|---|
| beforeCreate | - | 在setup之前执行 | 
| created | - | 在setup之前执行 | 
| beforeMount | onBeforeMount | 挂载开始前 | 
| mounted | onMounted | DOM挂载完成 | 
| beforeUpdate | onBeforeUpdate | 数据变更导致DOM更新前 | 
| updated | onUpdated | DOM更新完成后 | 
| beforeUnmount | onBeforeUnmount | 组件卸载前 | 
| unmounted | onUnmounted | 组件卸载完成 | 
Props深度处理
// 组件声明
export default {props: {userInfo: {type: Object,required: true,validator: (v) => v.age > 18}},setup(props) {// 安全解构方案const { userInfo } = toRefs(props)const userName = computed(() => userInfo.value.name)// 可选prop处理const theme = toRef(props, 'theme') // 等效props.theme || defaultreturn { userName }}
}
 
Context完整解析
setup(props, { attrs,     // 未声明的属性(相当于this.$attrs)slots,     // 插槽对象(相当于this.$slots)emit,      // 事件发射器(相当于this.$emit)expose     // 暴露公共API
}) {// 暴露指定方法expose({resetData: () => { /*...*/ }})// 事件发射示例const handleClick = () => {emit('custom-event', { data: 123 })}return { handleClick }
}
 
 
⚡ 响应式API体系
核心API对比
| API | 适用场景 | 深度响应 | 示例 | 
|---|---|---|---|
| ref | 基本类型/对象引用 | 浅层 | const num = ref(0) | 
| reactive | 复杂对象 | 深层 | const obj = reactive({}) | 
| shallowRef | 大型对象性能优化 | 浅层 | const bigData = shallowRef({}) | 
| readonly | 不可变数据 | 深层 | const copy = readonly(original) | 
| computed | 派生数据 | 自动 | const sum = computed(() => a+b) | 
| watch | 复杂侦听 | 可配置 | watch(source, callback, { deep: true }) | 
响应式转换原理
// ref实现原理简化版
function myRef(value) {const wrapper = {get value() {track(wrapper, 'value') // 依赖追踪return value},set value(newVal) {value = newValtrigger(wrapper, 'value') // 触发更新}}return wrapper
}
 
 
🧩 逻辑复用模式
自定义Hook示例
// useCounter.js
import { ref, computed } from 'vue'export default function useCounter(initialValue = 0) {const count = ref(initialValue)const double = computed(() => count.value * 2)function increment() {count.value++}function reset() {count.value = initialValue}return {count,double,increment,reset}
}// 组件使用
<script setup>
import useCounter from './useCounter'const { count, increment } = useCounter(10)
</script>
 
与Mixin对比优势
| 维度 | Mixin | 组合式函数 | 
|---|---|---|
| 命名冲突 | 容易发生 | 变量作用域隔离 | 
| 隐式依赖 | 需要查看mixin源码 | 显式参数传递 | 
| 类型支持 | 困难 | 完美支持TS | 
| 逻辑复用 | 整个mixin | 按需引用 | 
| 可测试性 | 困难 | 独立测试 | 
🏆 最佳实践
代码组织规范
<script setup>
// 1. 外部导入
import { useRouter } from 'vue-router'// 2. Props定义
const props = defineProps({title: String
})// 3. 事件定义
const emit = defineEmits(['submit'])// 4. 组合式函数
const { data } = useFetch('/api')// 5. 响应式状态
const searchQuery = ref('')// 6. 计算属性
const filteredList = computed(() => {return list.value.filter(item => item.includes(searchQuery.value))
})// 7. 生命周期
onMounted(() => {console.log('组件已挂载')
})// 8. 方法定义
function handleSubmit() {emit('submit', { data })
}// 9. 暴露API
defineExpose({reset: () => { searchQuery.value = '' }
})
</script>
 
性能优化技巧
-  
响应式优化:
// 批量更新 import { nextTick } from 'vue'const updateData = () => {data.value = bigDatanextTick(() => {// DOM更新后操作}) } -  
侦听器优化:
watch(() => props.list, (newVal) => {// 处理逻辑},{ deep: true, immediate: true } ) -  
内存管理:
onUnmounted(() => {// 清除定时器/事件监听 }) -  
组件分割:
// 大型组件拆分为多个<script setup>文件 import ChartSection from './ChartSection.vue' import DataTable from './DataTable.vue' 
