- 人工智能
- AI Agent
- MCP 服务
- 工具调用
- GUI 自动化
- 语音
- 数字人
- 交互助手
【免费下载链接】airi
💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。
导读
createRef是 VueUse 响应式(Reactivity)工具集中一个轻量而实用的工厂函数,其核心职责只有一个:根据deep布尔参数,返回一个浅层响应式的ShallowRef<T>,或一个深响应式的Ref<T>。在 airi 这类以 Vue 3 + Electron / Web 多端形态承载实时语音、弹幕、聊天与舞台渲染的复杂前端仓库中,深层对象监听的开销与浅引用带来的性能收益往往需要按场景取舍,createRef正是把这一决策收敛为一个带类型推导的函数调用的理想工具。读完本文,你将掌握createRef的完整类型签名、deep参数的语义边界,以及它在大规模 Vue 3 项目中与shallowRef的配合方式与适用场景。
createRef 是什么:一个参数决定深浅的引用工厂
createRef的函数签名极简:接收一个初始值value与可选的deep布尔参数,返回类型为CreateRefReturn<T, D>——即要么是ShallowRef<T>,要么是Ref<T>。文档对其的官方描述是:
Returns a
deepReforshallowRefdepending on thedeepparam.
也就是说,createRef本身并不发明新的响应式语义,而是将 Vue 3 原生ref(深响应)与shallowRef(浅响应)的选择逻辑封装为一个显式、可读、可类型推导的入口。这一点从它的类型定义可以看得很清楚:
export type CreateRefReturn< T = any, D extends boolean = false, > = ShallowOrDeepRef<T, D> export type ShallowOrDeepRef< T = any, D extends boolean = false, > = D extends true ? Ref<T> : ShallowRef<T>ShallowOrDeepRef是一个典型的条件类型(conditional type):当D为字面量true时,返回Ref<T>;否则(包括未传参时的默认false)返回ShallowRef<T>。这意味着返回值类型会随着调用参数被精确推断,createRef(1)在类型层面就是ShallowRef<number>,而createRef(1, true)就是Ref<number>,如下方官方文档示例所展示:
import { createRef } from '@vueuse/core' import { isShallow, ref } from 'vue' const initialData = 1 const shallowData = createRef(initialData) const deepData = createRef(initialData, true) isShallow(shallowData) // true isShallow(deepData) // falseisShallow是 Vue 3.4+ 提供的运行时判定 API,此处恰好充当了运行时验证:shallowData是浅引用,deepData是深引用。
deep 参数语义:何时浅、何时深
deep参数决定的是值变化时的追踪粒度,而不是响应式本身的有无——两者都是响应式引用,区别在于内部值:
createRef(value)或createRef(value, false):返回ShallowRef<T>。.value的整体替换会被追踪,但对.value内部嵌套属性(如value.obj.key = ...)的修改不会触发更新。适用于大型对象、频繁整体替换的引用(如 DOM 元素、组件实例、频繁重建的复杂数据结构)。createRef(value, true):返回Ref<T>。与 Vue 原生ref等价,会对对象内部嵌套属性做深层次响应式代理,适用于需要深度响应的小型状态对象。
从@__NO_SIDE_EFFECTS__注解可以看出,该函数是纯构建逻辑、无任何副作用,可以放心在模块顶层或热更新环境中重复调用。官方类型声明中的示例注释对四种调用形态做了完整罗列:
/** * @example createRef(1) // ShallowRef<number> * @example createRef(1, false) // ShallowRef<number> * @example createRef(1, true) // Ref<number> * @example createRef("string") // ShallowRef<string> * @example createRef<"A"|"B">("A", true) // Ref<"A"|"B"> * * @param value * @param deep * @returns the `deepRef` or `shallowRef` * * @__NO_SIDE_EFFECTS__ */ export declare function createRef<T = any, D extends boolean = false>( value: T, deep?: D, ): CreateRefReturn<T, D>值得注意的细节是:T默认是any,但可以通过显式泛型收窄(如createRef<"A"|"B">("A", true)得到Ref<"A"|"B">),让联合类型在深浅两种引用上都被完整保留。
完整类型声明与条件类型推导
将文档中的类型声明整体展开,可以归纳出三个层次:
CreateRefReturn<T, D>:对外暴露的返回类型别名,本质是ShallowOrDeepRef<T, D>;ShallowOrDeepRef<T, D>:核心条件类型,D extends true分支给出Ref<T>,否则给出ShallowRef<T>;createRef<T, D>函数重载签名:value: T、deep?: D,未传deep时D落入默认值false,从而默认返回浅引用。
这种设计在 TypeScript 使用者视角的价值在于:调用处无需任何类型断言,返回值就能与 Vue 的watch、templateRef、toValue等 API 正确对接。例如把createRef(initialData)的结果传给一个只接受ShallowRef的参数,编译器可以精确校验。
在 airi 仓库中的工程实践印证
createRef所属的 VueUse 库在 airi 仓库中是全量依赖的基础设施。根目录的 pnpm-workspace.yaml 中通过 catalog 统一固定了@vueuse/core与@vueuse/shared的版本为^14.4.0,从apps/component-calling、apps/stage-tamagotchi、apps/stage-web到packages/stage-ui、packages/electron-vueuse等十余个应用与包均通过"@vueuse/core": "catalog:"引用(例如 apps/stage-tamagotchi/package.json、packages/stage-ui/package.json),保证了整个 monorepo 内 VueUse 行为的一致。
虽然仓库内没有直接以createRef(...)字样调用(其用途常被shallowRef直接替代),但shallowRef的浅响应模式在整个 airi 前端代码中被大量使用,恰好印证了createRef默认分支所服务的场景:
- 在 packages/electron-vueuse/src/composables/use-electron-mouse-in-element.ts 中,鼠标坐标、元素包围盒等高频更新的数值状态全部使用
shallowRef(0)、shallowRef(true)初始化——这类值每次都是整体替换(elementX.value = elX),深响应毫无必要,浅引用避免了无谓的深度代理开销; - 在 apps/stage-tamagotchi/src/renderer/components/InteractiveArea.vue 中,语音录制状态
voicePending、voiceActive这类布尔开关同样用shallowRef(false)承载; - 在 apps/stage-tamagotchi/src/renderer/composables/use-chat-feed-expiry.ts 中,驱动消息过期计算的时钟
now被声明为shallowRef(Date.now()),每次仅通过.value =整体替换时间戳。
这些真实用例可以视为createRef(value)与createRef(value, false)的等价展开,说明在「高频整体替换 + 无嵌套追踪需求」的场景下,浅引用是 airi 前端工程中被验证过的合理默认选择;而需要深响应时,显式传入true即可,无需改换 API。
与 VueUse Reactivity 家族其他成员的协作定位
在 VueUse 的 Reactivity 分类中,createRef与若干函数在概念上相邻,理解它们的差异有助于在编码时做出正确选择(函数清单与调用规则见 .agents/skills/vueuse-functions/SKILL.md):
refDefault:为 ref 附加默认值,当.value为undefined时回退到默认值——解决的是「值缺失」问题,与createRef解决的「追踪深度」问题正交;toReactive:将对象型 ref 转换为 reactive,实现「可整体替换的响应式对象」——它面向对象解包场景,而createRef面向引用创建场景;toRef:将 value / ref / getter 归一化为 ref 或 computed——注意 VueUse 版toRef与 Vue 原生toRef行为不同,前者接受原始值与 getter、不接受object + key;extendRef:为 ref 附加额外属性(模板中不可见,ref 值会被自动解包)——与createRef组合使用时,可以先createRef得到深浅合适的引用,再extendRef附加元数据;createGlobalState:把状态提升到全局作用域跨 Vue 实例复用,其内部工厂函数同样常以shallowRef构建状态(如const count = shallowRef(0)),与createRef的浅引用理念一脉相承。
从决策链看:需要跨实例共享、持久化时优先createGlobalState+useStorage;需要为现有引用附加数据时用extendRef;而「新建一个引用、并且明确知道追踪深度」这一最小需求,正是createRef的定位。
使用建议与最佳实践
综合文档语义与 airi 仓库的工程实践,可以归纳出以下选型建议:
- 默认值偏好浅引用:
createRef(value)的默认行为就是浅引用,这与 VueUse 一贯「默认最小开销」的设计取向一致。如果你的状态每次都是整体赋值(如时间戳、坐标、布尔开关、DOM 引用),直接使用默认分支即可,无需手动传false。 - 显式深响应:当状态对象需要被深度修改并触发视图更新(例如嵌套的配置对象、表单模型)时,显式传
createRef(value, true),并在类型层面获得Ref<T>。 - 利用类型推导:借助
ShallowOrDeepRef条件类型,让deep参数参与返回类型计算,避免手写联合类型或类型断言,增强可维护性。 - 在 monorepo 中保持一致:airi 通过 pnpm-workspace.yaml 的 catalog 将
@vueuse/core固定在^14.4.0,使用createRef时应确认目标包已声明"@vueuse/core": "catalog:"依赖(参见各应用与包的package.json),确保运行时行为与本文示例一致。 - 运行时自检:若需在测试中验证深浅语义,可用 Vue 的
isShallow断言,如官方示例所示,这一能力在 airi 的 vitest 测试体系中可直接复用。
小结
createRef是 VueUse Reactivity 工具箱中一个「小而准」的工厂函数:它把 Vue 3 的深浅响应选择收敛为单一deep参数,并通过条件类型让返回类型随调用精确推导。无论是 airi 中高频更新的鼠标坐标、语音开关与时钟这类浅引用场景,还是需要深度追踪的复杂状态对象,createRef都提供了一条可读、可维护、类型安全的统一入口,是 Vue 3 响应式建模中值得纳入日常工具箱的基础工具。
- 人工智能
- AI Agent
- MCP 服务
- 工具调用
- GUI 自动化
- 语音
- 数字人
- 交互助手
【免费下载链接】airi
💖🧸 自托管、归你拥有的 Grok 风格 AI 伴侣与 waifu / 赛博生命灵魂容器,目标是接近 Neuro-sama 的高度;支持实时语音聊天、Minecraft 和 Factorio 游玩,支持 Web / macOS / Windows。
相关推荐
VueUse 的 createRef:按需创建深/浅响应式引用(Ref 与 ShallowRef 的统一入口)
VueUse 的 createRef:按需创建深/浅响应式引用(Ref 与 ShallowRef 的统一入口) 导读 createRef 是 VueUse 工具
前端VueUse createRef 使用指南:一个参数切换深层与浅层响应式引用
VueUse createRef 使用指南:一个参数切换深层与浅层响应式引用 导读 createRef 是 VueUse(Vue 3 组合式工具集)中一个轻量级
前端VueUse reactify 深入解析:把普通函数转换为响应式函数
VueUse reactify 深入解析:把普通函数转换为响应式函数 reactify 是 VueUse(Vue 3 组合式工具库)中位于 Reactivity
前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考