核心目标:深入理解从 Options API 到 Composition API 的范式转变,掌握逻辑复用(Composables)的高级技巧,建立数据驱动的代码组织思维。
📋 本章核心知识点
| 知识点 | 说明 | 难度 |
|---|---|---|
| 设计动机 | 为什么需要从 Options 转向 Composition | ⭐ |
| 生命周期 | Setup 中的钩子函数及其顺序 | ⭐⭐ |
| 逻辑复用 | 编写高质量的 Composables (useXxx) | ⭐⭐⭐⭐ |
| 响应式辅助 | toRefs, toRef, unref, isRef |
⭐⭐⭐ |
| 性能进阶 | shallowRef, triggerRef, markRaw |
⭐⭐⭐⭐ |
3.1 范式转变:解决"面条代码"
3.1.1 Options API 的局限性
在 Vue 2 中,处理同一个业务逻辑(如:搜索功能)的代码会被拆分到 data, methods, computed 中。当一个组件涉及 10 个业务逻辑时,开发者需要不停地上下滚动屏幕,代码难以维护且逻辑难以跨组件复用。
3.1.2 Composition API 的优势
- 按逻辑组织 :相关的代码写在一起,甚至提取到独立的
.ts文件中。 - 更好的类型推断:对 TypeScript 的支持是原生且完美的。
- 极致的复用性:通过函数组合而非 Minxin 继承。
3.2 逻辑复用之王:Composables (useXxx)
3.2.1 编写规范
Composable 函数应当:
- 以
use开头(约定俗成)。 - 输入参数可以是响应式的,输出通常是一个包含多个
ref的对象。 - 内部可以包含生命周期钩子(它会在调用处的组件中自动绑定)。
ts
// useMouse.ts
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouse() {
const x = ref(0)
const y = ref(0)
const update = (e: MouseEvent) => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
3.3 响应式全家桶:不仅仅是 ref
3.3.1 toRefs 与 toRef
直接解构并修改 reactive 对象会破坏响应式。toRefs 能将对象的所有属性转为 ref,从而支持解构。
ts
const person = reactive({ name: '张三', age: 18 })
const { name, age } = toRefs(person) // 此时 name 和 age 都是独立引用的 ref
3.3.2 unref 与 isRef
- isRef:检查值是否为 ref。
- unref :如果参数是 ref,返回内部值,否则返回参数本身(相当于
val = isRef(v) ? v.value : v)。常用于工具函数中处理参数归一化。
3.4 性能优化的暗门:Shallow 系统
3.4.1 shallowRef 与 shallowReactive
- 背景:Vue 默认的响应式是"深度"的,对于一个有 1000 个层级的庞大对象,Vue 会递归遍历。
- 优化 :
shallowRef只监听.value的指向变化。如果你只是展示大数据(如从后端拿到的 1 万条清单),使用shallowRef能节省巨大的 CPU 初始化开销。
3.4.2 markRaw
禁止一个对象被响应式转换。通常用于存储第三方库实例(如 ECharts、Mapbox),因为它们的内部属性极其庞大,被 Vue 代理后会导致严重的卡顿。
3.5 最佳实践:如何写出优雅的 setup
- 保持 Setup 简单 :复杂的业务逻辑一律抽离成
useXxx函数。 - 避免在 setup 中使用 this :在组合式 API 中,
this不是指向组件实例。 - 合理搭配生命周期 :网络请求放在
onMounted,资源清理放在onBeforeUnmount。
🔗 专栏链接 :Vue 3 全栈开发实战专栏
📦 项目源码资源 :点击下载项目源码