第三章: Vue 3组合式 API(Composition API)

核心目标:深入理解从 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 函数应当:

  1. 以 use 开头(约定俗成)。
  2. 输入参数可以是响应式的,输出通常是一个包含多个 ref 的对象。
  3. 内部可以包含生命周期钩子(它会在调用处的组件中自动绑定)。
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

  1. 保持 Setup 简单 :复杂的业务逻辑一律抽离成 useXxx 函数。
  2. 避免在 setup 中使用 this :在组合式 API 中,this 不是指向组件实例。
  3. 合理搭配生命周期 :网络请求放在 onMounted,资源清理放在 onBeforeUnmount。

🔗 专栏链接 :Vue 3 全栈开发实战专栏

📦 项目源码资源 :点击下载项目源码

相关推荐
夏幻灵2 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记2 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习2 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194053 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风4 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn5 小时前
框架性能优化
前端
雪芽蓝域zzs7 小时前
第 5 节:Marker 点击弹出 InfoWindow 信息窗口
vue.js
回眸&啤酒鸭7 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013847 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员7 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端