Vue 生态(番外):Vue 生态精髓:VueUse 全解,助你精通前端逻辑复用

番外篇:VueUse · 从“函数字典”到“能力地图”的思维革命

摘要: VueUse (v13.x) 拥有超过 200 个组合式函数,试图“记住”它们是一条死胡同。本章的唯一目的,是引导你完成一次彻底的思维革命:从一个被动记忆 API 的“学习者”,转变为一个主动调度能力的“架构师”。我们将首先彻底粉碎“记忆负担”,建立一套无懈可击的“意图 -> 检索 -> 应用”心智模型。随后,我们将共同绘制一幅 VueUse 的“能力地图”,将所有函数划分到几个核心“能力域”。最后,我们将通过一系列真实场景驱动的实战,演练如何按图索骥,并掌握专业级的最佳实践。忘记字典,从现在开始,让我们学会使用地图。


本章地图

在本章中,我们将像一位经验丰富的探险家,遵循一条清晰的路径来征服 VueUse 这片广袤的领域:

  1. 首先,我们将直面最大的敌人——“记忆负担”,并掌握一套能彻底解放大脑的思维模式
  2. 接着,我们将绘制并学习使用我们的核心工具——“VueUse能力地图”,学会如何为任何需求进行精准的“能力定位”。
  3. 然后,我们将进入核心实战环节,按图索骥,学习如何运用不同“能力域”的力量,优雅地解决真实世界的开发难题。
  4. 最后,我们将打磨探险的技巧,掌握专业级的最佳实践,确保我们的代码既高效又健壮。

第一章:思维革命:停止记忆,开始调度!

本节旨在从根本上转变读者的思维模式,是整个番外篇的基石。

1.1. 痛点:为什么“学习”VueUse 是个伪命题?

痛点背景: 面对 VueUse 庞大的函数库,开发者最常见的困境是:“我该用哪个?我怎么知道有这个函数?” 这种不确定性导致了两个极端:要么花费大量时间死记硬背,要么在需要时因遗忘而重新“造轮子”,费时费力且容易出错。这两种方式都极大地扼杀了我们的开发效率和创造力。

问题的根源在于,我们错误地将 VueUse 当作了一门需要“学习”和“背诵”的课程。实际上,VueUse 不是用来“学”的,而是用来“用”的。它是一个工具箱,你的目标不是记住每一把扳手的尺寸,而是知道在拧不同螺丝时,应该去工具箱的哪个格子里寻找。

1.2. 解决方案:建立“意图驱动”的心智模型

真正的专业人士从不依赖记忆,而是依赖体系。 我们需要将大脑从“存储器”的角色中解放出来,使其成为一个“调度器”。这套工作流就是你的指挥系统。

2025

明确意图

在动手写任何通用逻辑前,停顿三秒。用最直白的大白话问自己:“我的意图是什么?”

  • 反例: “我要写一个 onMounted,然后 window.addEventListener('scroll', ...)” (这是实现细节)

  • 正例: “我的意图是:需要知道用户滚动到了哪里。” (这是核心需求)

能力定位

拿着你的“意图”,对照我们即将绘制的“能力地图”,迅速定位它属于哪个能力域

  • “滚动”这个行为,显然属于与用户物理交互的 “传感器 (Sensors)” 领域。

精准检索

进入 VueUse 官网,像使用搜索引擎一样,输入你意图的关键词。

  • 在搜索框中输入 scroll

应用与内化

官网会立即展示 useScroll。通过其交互式 Demo 快速验证它是否满足需求,然后将其应用到你的代码中。每一次成功的应用,都在加深你对这张“能力地图”的理解。

这个流程将成为你的第二天性。它将你的关注点从“我该怎么写”,提升到了“我需要什么能力”的更高维度。


第二章: 绘制你的“能力地图”:VueUse 核心能力域索引

在上一节中,我们确立了“意图驱动”的思维模式。现在,我们需要一张能够承载这种思维模式的“地图”。本节的核心任务就是绘制并熟悉这张地图,为后续的“按图索骥”提供导航。

2.1. 地图图例:理解六大核心“能力域”

痛点背景: 如果将 VueUse 的 200 多个函数平铺在你面前,你依然会感到不知所措。我们需要一个更高维度的视角来组织它们,就像地理学家将世界划分为不同的大洲一样。我们将 VueUse 的所有功能,归纳为六个核心的“能力域”或“能力大陆”。

解决方案: 这张表格就是你的“地图图例”。它定义了每个能力域的核心职责与探索时机。在未来的开发中,任何一个“意图”都应该能被你快速地映射到其中一个“大陆”上。

能力域 (大陆)核心职责 (这是什么地方?)探索时机 (什么时候来这里?)
传感器响应物理世界或用户的直接输入。当你需要处理鼠标、键盘、滚动、设备状态、元素聚焦等交互时。
元素赋予你响应式地操控和观察 DOM 元素的能力。当你需要知道元素的尺寸、位置、可见性,或想让它可拖拽、可观测时。
浏览器优雅地封装了浏览器提供的原生 API。当你需要操作剪贴板、全屏、URL、标题、本地存储时。
状态提供了强大的工具来增强和管理你的响应式状态。当你需要持久化状态、实现撤销/重做、防抖/节流、异步状态管理时。
动画简化了创建流畅动画和时间相关操作的复杂度。当你需要处理定时器、时间戳、补间动画、帧动画循环时。
工具集一系列无法被简单归类,但极其有用的通用助手。当你需要切换状态、异步队列、格式化、事件总线等通用能力时。

请花一分钟熟悉这张表格。它是我们后续所有实战章节的导航基础。


2.2. 热点区域标注:各能力域中的“明星函数”

痛点背景: 即便知道了要去哪个“大陆”,面对广袤的土地,我们依然需要知道哪些是必去的“著名景点”。直接深入到每一个函数会耗费太多精力,对于初学者,我们需要先抓住重点。

解决方案: 我们为每个能力域都标注出了 2-3 个使用频率最高、最具代表性的“明星函数”。掌握了它们,你就掌握了这个能力域 80% 的核心应用场景。

  • 传感器 (Sensors)

    • useMouse: 跟踪鼠标坐标。
    • useScroll: 监听滚动事件,并返回滚动位置和状态。
    • onKeyStroke: 监听特定的键盘按键事件,轻松实现快捷键功能。
  • 元素 (Elements)

    • useElementVisibility: 判断一个元素是否在视口(Viewport)中可见,懒加载必备。
    • useDraggable: 让一个元素变得可以自由拖拽。
    • useElementSize: 响应式地获取一个元素的宽度和高度。
  • 浏览器 (Browser)

    • useClipboard: 轻松实现复制到剪贴板功能。
    • useTitle: 动态地、响应式地修改页面标题。
    • useUrlSearchParams: 便捷地读取和操作 URL 的查询参数。
  • 状态 (State)

    • useStorage: (强烈推荐) 将一个 reflocalStoragesessionStorage 双向绑定,极其方便。
    • useAsyncState: (强烈推荐) 优雅地管理异步操作的所有状态(isLoading, isReady, error, data)。
    • useRefHistory: 记录一个 ref 的修改历史,轻松实现撤销和重做功能。
  • 动画 (Animation)

    • useIntervalFn: 以响应式的方式使用 setInterval,并在组件销毁时自动清除。
    • useTransition: 实现数值变化的补间动画,常用于数字滚动效果。
  • 工具集 (Utilities)

    • useToggle: 在 truefalse 之间切换,非常基础但常用。
    • useDebounceFn: 将一个函数包装成防抖函数。
    • useEventBus: 创建一个全局或局部的事件总线,用于跨组件通信。

这份“明星函数”列表是你快速入门 VueUse 的捷径。在你还不熟悉整个库时,优先在你的项目中尝试使用它们,你会立刻感受到效率的巨大提升,从而建立起正向的学习反馈。


第三章:按图索骥:在真实场景中运用能力

在上一章,我们绘制并熟悉了“VueUse 能力地图”。现在,是时候放下理论,卷起袖子,将地图上的知识应用到真实的“战场”了。本章,我们将从零开始,构建一个完整可运行的微型“在线笔记”应用,让你亲手体验组合式函数如何将复杂的交互逻辑变得简单而优雅。

image-20250902162117613

3.1. 准备战场:初始化 Vite + Vue 3 项目

架构思想: 一个标准化的、干净的项目开端是高效开发的基石。我们将使用 Vite,社区公认的最快、最现代化的前端构建工具,来初始化我们的项目。

首先,请确保你的电脑已安装 Node.js (LTS 版本) 和 pnpm。打开你的终端(例如 PowerShell 或 Windows Terminal),执行以下命令:

1
2
# 1. 使用 Vite 官方脚手架创建项目,选择 Vue 和 TypeScript
pnpm create vite vueuse-notebook --template vue-ts

接着,进入项目目录并安装依赖:

1
2
3
4
5
6
7
8
# 2. 进入项目目录
cd vueuse-notebook

# 3. 安装项目依赖
pnpm install

# 4. 安装 VueUse
pnpm add @vueuse/core

3.2. 搭建骨架:创建项目文件结构

架构思想: 清晰的文件组织是项目可维护性的关键。我们将模拟一个真实项目的结构,将逻辑(Composables)与视图(Components)分离。

为了方便,我们提供 Windows PowerShell 下一键创建目录和文件的命令。请在项目根目录 (vueuse-notebook) 下执行:

1
2
# 在 PowerShell 中执行以下命令
New-Item src\components\NoteEditor.vue; New-Item src\App.vue -Force

执行后,你的 src 目录结构应该如下所示:

1
2
3
4
5
6
# src/
├── App.vue # <-- 我们将在这里整合所有功能
├── assets/
├── components/
│ └── NoteEditor.vue # <-- 笔记编辑器的核心组件
└── main.ts

New-Item ... -Force 命令会覆盖 App.vue,方便我们从一个干净的文件开始。


3.3. 功能实现:构建一个“活”的笔记应用

现在,激动人心的编码环节开始了。我们将分两步,先构建核心编辑器组件,然后在 App.vue 中将其与更多交互功能组合起来。

第一步:打造核心编辑器 NoteEditor.vue

承上启下: 编辑器是应用的核心。我们将在这个组件中实现最基础的持久化存储撤销/重做功能。

文件路径: src/components/NoteEditor.vue (修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<script setup>
import { useStorage, useRefHistory } from '@vueuse/core'

// 1. 来自【状态】域:使用 useStorage 将笔记内容与 localStorage 同步
// UseStorage(key, initialValue)
const content = useStorage("notebook-content", "你好,VueUse!")

// 2. 来自【状态】域:使用 useRefHistory 追踪 content 的变化历史
// 他会返回两个函数和两个布尔值
const { undo, redo, canUndo, canRedo } = useRefHistory(content, { capacity: 10 }) // 最多记录10步历史


</script>

<template>
<div class="note-editor">
<div class="toolbar">
<!-- disabled:对于canUndo取反就代表着当没有撤销记录时,按钮不可点击 -->
<button @click="undo" :disabled="!canUndo">撤销</button>
<button @click="redo" :disabled="!canRedo">重做</button>
</div>
<textarea v-model="content" placeholder="开始记录..."></textarea>
</div>
</template>
<!-- 需要安装scss:pnpm add -D sass -->
<style scoped lang="scss">
.note-editor {
width: 400px;
height: 200px;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;

.toolbar {
background-color: #f7f7f7;
padding: 8px;
border-bottom: 1px solid #ccc;

button {
margin-right: 8px;
}
}

textarea {
width: 100%;
height: 300px;
border: none;
padding: 12px;
box-sizing: border-box;
font-size: 16px;
resize: vertical;
}

textarea:focus {
outline: none;
}

}
</style>

第二步:在 App.vue 中组合更多能力

承上启下: 有了核心编辑器,我们现在要在主应用中为其赋予更多“超能力”,比如动态标题可拖拽面板快捷键

文件路径: src/App.vue (修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<script setup lang="ts">
import { ref } from 'vue'
import { useTitle, useDraggable, onKeyStroke, useMouse, useWindowSize } from '@vueuse/core'
import NoteEditor from './components/NoteEditor.vue'

// 来自【浏览器】域:动态标题
const noteTitle = ref('我的在线笔记')
useTitle(() => `📝 ${noteTitle.value}`) // 标题将响应式地变化

// 来自【元素】域:可拖拽的“信息面板”
const infoPanel = ref<HTMLElement | null>(null)
const { width } = useWindowSize()
const { style } = useDraggable(infoPanel, {
// 面板初始位置在右上角
initialValue: { x: width.value - 260, y: 20 },
})

// 来自【传感器】域:监听 Ctrl+S 组合键
onKeyStroke('s', (e) => {
if (e.ctrlKey || e.metaKey) { // 支持 Windows/Linux 的 Ctrl 和 Mac 的 Cmd
e.preventDefault()
alert('笔记已"云同步"!(模拟)')
}
})

// 来自【传感器】域:获取鼠标位置
const { x, y } = useMouse()
</script>

<template>
<main>
<h1>
<input v-model="noteTitle" class="title-input" />
</h1>
<note-editor />

<!-- 可拖拽的信息面板 -->
<div ref="infoPanel" :style="style" class="info-panel">
<h4>信息面板</h4>
<p>鼠标位置: {{ x }}, {{ y }}</p>
<p>按 Ctrl + S 可“云同步”</p>
</div>
</main>

</template>


<style scoped lang="scss">

.title-input {
width: 100%;
border: none;
font-size: 2rem;
font-weight: bold;
background: transparent;
border-bottom: 2px solid transparent;
transition: border-color 0.3s;

&:focus {
outline: none;
border-bottom-color: #42b883;
}
}

/* 信息面板样式 */
.info-panel {
position: fixed;
cursor: move;
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
width: 240px;
}
</style>

3.4. 见证实战成果:运行你的应用!

所有代码已经就绪。现在,回到你的终端,确保你仍在 vueuse-notebook 目录下,然后启动开发服务器:

1
pnpm dev

Vite 会启动一个本地开发服务器。在浏览器中打开它提供的地址(通常是 http://localhost:5173),你将看到一个功能齐全的笔记应用!

亲自体验一下:

  1. 编辑内容:在文本域中输入或删除文字,然后刷新页面,你会发现内容被完美保留了 (useStorage)。
  2. 撤销/重做:点击按钮,体验需要手动封装栈才能实现的撤销和重做操作 (useRefHistory)。
  3. 修改标题:编辑顶部的标题,观察浏览器标签页的变化 (useTitle)。
  4. 拖拽面板:按住“信息面板”并拖动它到任意位置 (useDraggable)。
  5. 快捷键:按下 Ctrl + S,看看会发生什么 (onKeyStroke)。

恭喜你!你已经不再是理论的旁观者,而是实践的参与者。通过这个迷你项目,你亲身体验了如何将来自不同“能力域”的 VueUse 函数组合在一起,像拼搭乐高一样,快速、高效地构建出强大的交互功能。


第四章:专业的探险技巧:VueUse 最佳实践

在掌握了“如何用”之后,本章将拔高一层,讲解“如何用得好”。精通工具和仅仅会用工具,是区分专业工程师与普通开发者的重要标志。我们将学习 VueUse 官方推荐的设计哲学与最佳实践,这些技巧将让你的代码更加专业、健壮和灵活。

4.1. 响应式哲学:理解 MaybeRefOrGetter

痛点背景: 在我们自己封装逻辑时,常常会写出这样的代码:function doSomething(value) { ... }。如果传入的 value 是一个 ref,我们在函数内部就必须时刻记着使用 .value 来访问它。这不仅繁琐,而且限制了函数的灵活性。

解决方案: VueUse 推广了一种极其强大的类型工具——MaybeRefOrGetter。它代表一个值可以是普通值、一个 ref,或者一个返回值的函数 (getter)。VueUse 内部通过 toValue() 工具函数来智能地“解包”,让你无需关心传入的到底是什么形态。

这意味着 VueUse 函数的参数天然就是响应式的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { ref, computed } from 'vue'
import { useTitle } from '@vueuse/core'

const count = ref(0)
const staticTitle = '静态标题'

// 场景1:传入一个 ref (ComputedRef 也是 ref)
// useTitle 会自动解包 ref,并监听其 .value 的变化
// 这种写法是清晰的,但为了一次性使用而创建 computed 实例略显多余
const dynamicTitle = computed(() => `计数器: ${count.value}`)
useTitle(dynamicTitle)

// 场景2:传入一个 getter 函数 (最推荐、最高效的方式)
// 没有创建额外的 computed 实例,`useTitle` 内部直接 watch 这个 getter 函数
useTitle(() => `计数器: ${count.value}`)

// 场景3:传入一个普通值
// 标题只会被设置一次,不会再变化
useTitle(staticTitle)

setInterval(() => count.value++, 1000)

// ---------------------------------------------------
// toValue() 的工作原理:
console.log(toValue(count)) // 输出 ref 的 .value 值
console.log(toValue(() => count.value * 2)) // 执行 getter 函数并返回值
console.log(toValue(staticTitle)) // 直接返回值

架构师思维:在封装你自己的 Composable 时,也应该遵循此范式。让你的函数接受 MaybeRefOrGetter 类型的参数,并在内部使用 toValue() 来处理,这将使你的逻辑单元获得无与伦比的灵活性和可组合性。


4.2. 副作用管理:tryOnScopeDispose 与自动清理

痛点背景: 在 JavaScript 中,手动管理事件监听、定时器、WebSocket 连接等“副作用”是导致内存泄漏的主要原因。我们常常忘记在组件卸载时调用 removeEventListenerclearInterval

解决方案: VueUse 已经为你完美地解决了这个问题。它的所有会产生副作用的函数(如 useEventListener, useIntervalFn),内部都使用了 Vue 3.2+ 提供的 effectScope API 或 tryOnScopeDispose 工具。

核心机制

作用域绑定

当你在组件的 setup 作用域内调用一个 VueUse 函数时,这个函数内部创建的所有副作用,都会被自动“注册”到当前组件的生命周期作用域中。

自动销毁

当该组件被卸载(onUnmounted)时,Vue 会自动销毁这个作用域,并触发所有已注册的“清理函数”(例如 removeEventListener)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup lang="ts">
import { useEventListener, useIntervalFn } from '@vueuse/core'

// 这个事件监听器会在组件卸载时自动被移除
useEventListener(window, 'mousemove', (event) => {
console.log(event.clientX)
})

// 这个定时器会在组件卸载时自动被 clearInterval
const { pause, resume } = useIntervalFn(() => {
console.log('Interval tick')
}, 1000)

// 你无需编写任何 onUnmounted 代码来进行清理!
</script>

这种“自动清理”机制是你应该信赖并利用的核心特性。它让你能够专注于业务逻辑,而不必为资源管理的细节而分心。


4.3. 配置的力量:options 对象

痛点背景: 一个好的工具不仅要简单易用,还要能在复杂场景下提供足够的“逃生舱口”。如果一个函数的所有行为都被硬编码,那么当遇到特殊需求时(例如在测试环境中、或是在 iframe 中操作),它就会变得毫无用处。

解决方案: VueUse 的绝大多数函数都接受一个可选的 options 对象作为最后一个参数。这个对象为你提供了深度定制其行为的能力。

最常见的几个配置项:

  • 事件过滤器 (eventFilter): 轻松为事件添加防抖(debounceFilter)或节流(throttleFilter)。

    1
    2
    3
    4
    5
    6
    import { useScroll, debounceFilter } from '@vueuse/core'

    // 只有当滚动停止 300ms 后,才会更新 x 和 y 的值
    const { x, y } = useScroll(window, {
    eventFilter: debounceFilter(300),
    })
  • 可配置的全局依赖 (window, document): 允许你将函数的执行上下文从当前 window 切换到其他环境,例如 iframecontentWindow 或测试中的 mock 对象。

    1
    2
    3
    4
    5
    6
    import { useTitle } from '@vueuse/core'

    const iframe = document.querySelector('iframe')

    // 这将修改 iframe 内部的标题,而不是主窗口的
    useTitle('Iframe Title', { document: iframe.contentDocument })
  • watch 相关选项 (flush, deep): 对于那些内部依赖 watch 的函数(如 useStorage),你可以传递所有 watch 支持的选项,来精细控制其响应时机和深度。

    1
    2
    3
    4
    5
    6
    import { useStorage } from '@vueuse/core'

    // 当 userSettings 内部嵌套的属性变化时,也会触发写入 localStorage
    const userSettings = useStorage('settings', { theme: 'dark', layout: { width: 1200 } }, {
    deep: true, // 开启深度监听
    })

第五章:总结与展望

我们已经一同走过了 VueUse 的思维革命、地图绘制、实战演练和技巧打磨。在这次探险的终点,让我们回顾一下最重要的收获,并通过模拟面试的形式,将知识内化为真正的能力。

5.1. 本章核心速查总结

这份表格浓缩了本章我们所学到的最重要的思想、工具和原则。当你未来在项目中准备使用 VueUse 时,可以快速回顾它,以确保你的思路和实践都保持在正确的轨道上。

分类关键原则/能力核心描述
核心思想意图驱动工作流(黄金法则) 忘记记忆,专注需求。通过“意图 -> 定位 -> 检索 -> 应用”的流程,将 VueUse 官网当作你的外部大脑来解决问题。
核心工具能力地图与分类索引使用“传感器、元素、浏览器、状态、动画、工具集”这六大能力域,为你的任何一个开发“意图”进行快速的功能定位。
核心实践响应式参数优先使用 Getter 函数 (`() => value.ref`) 的形式传递响应式参数,这是最高效、最灵活的方式。
核心实践自动副作用清理完全信赖 VueUse 的自动清理机制。在组件 setup 中使用的函数,其副作用(事件、定时器等)会在组件销毁时被自动回收,无需手动管理。
核心实践善用 options 配置当遇到复杂场景时,记得查阅函数的 options 对象,它为你提供了事件过滤、依赖注入等强大的定制能力。

5.2. 高频面试题与架构师思维

以下模拟面试将考察你是否真正理解了 VueUse 的设计哲学,而不仅仅是停留在会用 API 的层面。

VueUse 深度考察
2025-11-01

VueUse 极大地提升了开发效率,但如果过度使用,会不会导致项目最终打包体积过大?你是如何看待这个问题的?

这是一个很好的问题,它涉及到工程化的权衡。首先,VueUse 是完全可摇树 (Tree-Shakable) 的。这意味着我们最终的打包产物中,只会包含我们实际 import 使用到的那些函数,而不会引入整个库。所以,只要我们是按需引入,就不用担心打包体积的问题。其次,从架构角度看,自己手写类似功能的逻辑,代码量和复杂度往往会远超 VueUse 中经过优化的实现。因此,合理使用 VueUse 反而是减小业务代码体积、提升代码质量和可维护性的最佳实践。

非常好。那么,当你在封装一个自己的、可能会被团队复用的 Composable 时,你会从 VueUse 的设计中学到哪些可以借鉴的原则?

我会借鉴四点核心原则。第一,响应式接口:函数的输入和输出都应该是响应式的,参数接受 MaybeRefOrGetter 类型,并在内部用 toValue() 处理,返回值也是 ref 对象。第二,自动清理:通过 tryOnScopeDispose 确保所有副作用都能被自动管理,让使用者无需关心清理逻辑。第三,配置化:通过一个 options 对象来提供更灵活的配置,比如 window, document 的注入,或者 flush, immediatewatch 选项,使其在 SSR 或测试环境中更易用。第四,提供 isSupported 标志:如果封装的逻辑依赖于特定的浏览器 API,应该提供一个 isSupported 的 ref,让使用者可以优雅地处理兼容性问题。这四点共同构成了一个健robust, flexible, and professional Composable.


5.3. 你的下一站:从“使用者”到“贡献者”

我们对 VueUse 的探索至此告一段落,但这绝不是终点。你已经掌握了高效使用它的思维模式和方法。接下来,你可以:

  1. 全面探索: 将 VueUse 官方文档 加入你的浏览器收藏夹。在遇到任何通用需求时,都将它作为你的第一参考。
  2. 深入源码: 当你对某个函数的实现原理感到好奇时(例如 useRefHistory 是如何工作的?),不要犹豫,直接去 GitHub 上阅读它的源码。VueUse 的代码库非常清晰、规范,是学习组合式函数写法的最佳范例。
  3. 成为贡献者: 如果你发现了一个 Bug,或者有了一个新的、通用的 Composable 的想法,可以尝试向 VueUse 社区提交 Issue 甚至 Pull Request。参与到顶级开源项目中,将是让你技术水平发生质的飞跃的宝贵经历。