AIRI 项目 VueUse 指南:用 useZoomLevel 在 Electron 桌面端响应式控制窗口缩放级别
【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi
useZoomLevel是 VueUse 的@vueuse/electron扩展包中用于 Electron 渲染进程的 composable,它把WebFrame的缩放级别(zoom level)包装成一个可双向读写的 VueRef。本文基于 AIRI 仓库中内置的 VueUse 函数参考文档(.agents/skills/vueuse-functions/references/useZoomLevel.md)完整讲解其三种调用形态、重载签名与nodeIntegration前提,并结合 AIRI 的 Electron 桌面应用(apps/stage-tamagotchi)与自研@proj-airi/electron-vueuse包说明它在本仓库中的定位与适用边界。
useZoomLevel 解决什么问题
Electron 的渲染进程可以通过WebFrameAPI 调整页面的缩放级别。缩放级别是一个整数(默认值为0,即 100% 缩放),与缩放因子(zoom factor)的关系为:缩放因子 = 1.2 的缩放级别次方,即zoomFactor = 1.2 ** zoomLevel。例如级别1对应约 120% 缩放,级别-1对应约 83% 缩放。
在 Electron 渲染进程里手写响应式缩放逻辑,通常需要自行处理:
- 读取当前级别(
webFrame.getZoomLevel()); - 监听外部变化并同步到状态;
- 在状态变化时写回
webFrame.setZoomLevel(...); - 处理初始值的立即写入。
useZoomLevel把这套流程收敛为一个 composable:返回的Ref<number>既反映当前缩放级别,又可以在赋值时直接改变缩放级别,且会自动跟随源ref的变化持续同步。
该参考文档在 AIRI 仓库中的位置
AIRI 仓库通过一份内置的 VueUse 技能参考来约束开发过程中的函数选型。参考文档 useZoomLevel.md 的 frontmatter 标注其类别为@Electron,表明它属于 VueUse 的 Electron 扩展包(@vueuse/electron),而非核心包。
从仓库的同步信息 SYNC.md 可以看到,这份参考是从 VueUse 上游的技能目录同步而来的,锁定的 Git SHA 为b6bb79b99fb1f1dba1f907829676a651735bbc10,同步日期为 2026-06-22。也就是说,文档内容以上游 VueUse 的版本为准,可作为useZoomLevel语义的权威参考。
技能总表 SKILL.md 对函数规定了三种调用策略(AUTO自动使用 /EXTERNAL需已安装外部依赖才使用 /EXPLICIT_ONLY仅在用户明确要求时使用)。useZoomLevel被列为EXTERNAL:
| Function | Description | Invocation |
|---|---|---|
useZoomLevel | Reactive WebFrame zoom level | EXTERNAL |
这意味着在 AIRI 的协作约定里,只有当项目(或调用方)已经安装@vueuse/electron依赖时,才应当选用该函数,而不是默认引入。
完整用法:三种调用形态
以下用法完整继承自参考文档,并补充了参数语义说明。
1. 默认形态:读取并控制当前页面的缩放级别
import { useZoomLevel } from '@vueuse/electron' // 若没有显式传入 webFrame,则要求开启 nodeIntegration // 返回的 Ref 反映当前缩放级别 const level = useZoomLevel() console.log(level.value) // 打印当前缩放级别 level.value = 2 // 将当前缩放级别改为 2(约 144%)- 不带参数调用时,composable 默认操作当前页面的
WebFrame; - 文档明确提示:如果未显式传入
webFrame实例,需要开启nodeIntegration(否则渲染进程中拿不到 Electron 注入的webFrame对象); - 返回值是
Ref<number>,level.value可读可写,读即获取当前级别,写即调用WebFrame.setZoomLevel。
2. 传入初始级别:挂载后立即生效
import { useZoomLevel } from '@vueuse/electron' const level = useZoomLevel(2) // 初始化时立即把缩放级别设为 2第一个参数为纯数值时,表示“初始缩放级别”:composable 会在初始化时立刻将 WebFrame 的缩放级别设置为该值,适合在界面布局完成前就固定一个缩放状态(例如根据用户偏好恢复上次保存的级别)。
3. 传入 ref:级别与外部状态双向跟随
import { useZoomLevel } from '@vueuse/electron' import { shallowRef } from 'vue' const level = shallowRef(1) useZoomLevel(level) // 缩放级别将与该 ref 保持一致 level.value = 2 // 缩放级别随之改变这是最贴近响应式场景的形态:传入一个MaybeRef<number>(ref、shallowRef或普通数值均可)作为源状态,useZoomLevel会持续把 WebFrame 的实际缩放级别同步到源ref,并在源ref变化时写回 WebFrame。典型应用是:把缩放级别存入持久化偏好(如useLocalStorage风格的 ref),重启应用后自动恢复到用户上次选择的级别。
类型声明与重载选择
参考文档给出的完整类型声明如下:
export declare function useZoomLevel(level: MaybeRef<number>): Ref<number> export declare function useZoomLevel( webFrame: WebFrame, level: MaybeRef<number>, ): Ref<number> export declare function useZoomLevel(webFrame: WebFrame): Ref<number> export declare function useZoomLevel(): Ref<number>四个重载覆盖了两类参数的全组合,可以按如下方式理解:
| 参数组合 | 含义 | 适用场景 |
|---|---|---|
useZoomLevel() | 默认 WebFrame,无初始值 | 只需读取/控制当前页面缩放 |
useZoomLevel(level) | 默认 WebFrame + 初始级别或源 ref | 立即设定初始级别,或绑定一个外部状态 |
useZoomLevel(webFrame) | 显式指定目标 WebFrame | 操作<webview>等独立帧,规避 nodeIntegration 依赖 |
useZoomLevel(webFrame, level) | 显式 WebFrame + 初始级别或源 ref | 对独立帧同时做初始化和状态绑定 |
其中level的参数类型是MaybeRef<number>,即“普通数值或 ref 皆可”:传数值时它是初始值;传 ref 时它是需要同步的源状态,这也是上面三种用法能共用同一函数名的原因。
值得对照的是同一参考目录下的 useZoomFactor.md,其签名结构完全同构,只是操作的是缩放因子(任意正实数,如1.25、1.5)而非缩放级别(离散整数)。级别适合表达“放大一级/缩小一级”的步进语义(Ctrl++/ Ctrl+-快捷键),因子适合表达精确的百分比缩放,两者可以按1.2 ** level互相换算。
关键前提与注意事项
- nodeIntegration 前提:文档中的注释明确指出,若不显式传入
webFrame,需要开启nodeIntegration。在强调安全性的生产应用中,更推荐的做法是通过webPreferences/ preload 拿到目标WebFrame实例后显式传入,从而避免依赖渲染进程的全局 Node 能力。 - 仅限 Electron 环境:
useZoomLevel依赖 Electron 的WebFrameAPI,在纯浏览器页面(如 AIRI 的 Web 端)中不存在对应能力,只能在 Electron 渲染进程中运行。 - 依赖前提:该函数来自独立包
@vueuse/electron。按 SKILL.md 的EXTERNAL约定,只有已安装该包时才应使用;AIRI 各工作区包目前普遍通过 catalog 引入的是@vueuse/core与@vueuse/shared(例如 apps/stage-tamagotchi/package.json),并未直接引入@vueuse/electron。
AIRI 的 Electron composable 生态:useZoomLevel 在仓库中的定位
为了说明useZoomLevel与 AIRI 自身代码的关系,有必要看一下仓库里 Electron 场景下真正被复用的 composable 层。AIRI 维护了一个内部包@proj-airi/electron-vueuse,其自述是“VueUse-like composables and helpers for Electron apps”,见 packages/electron-vueuse/README.md。从 package.json 的依赖声明可以看出它的定位:
peerDependencies要求electron: ">=39 <44"、vue: ">=3",这就是 AIRI Electron 生态的适用版本前提;dependencies中包含@vueuse/core(catalog 版本),即 AIRI 自研的 Electron composable 是建立在@vueuse/core之上的,而不是直接使用@vueuse/electron。
该包提供的能力集中在窗口/鼠标/自动更新等高频场景(README 列出mouse、window bounds、auto updater等),例如 use-electron-window-bounds.ts 展示了 AIRI 惯用的模式:通过 Eventa IPC 契约监听主进程推送的窗口边界事件,把x/y/width/height收敛为一组ref供渲染进程消费。
从源码结构看,当前仓库中没有找到任何直接import { useZoomLevel } from '@vueuse/electron'的调用点,各桌面端应用(如 apps/stage-tamagotchi)也没有声明@vueuse/electron依赖。因此可以推断:useZoomLevel在 AIRI 中属于技能参考层面预留的可选扩展能力——当桌面端(如 Tamagotchi 桌面应用)未来需要“界面缩放级别”这类功能(例如聊天字号缩放、舞台视口缩放偏好持久化)时,开发者可以在已引入@vueuse/electron的前提下,按本文的三种形态直接套用,而不必手写 WebFrame 的读写与同步逻辑。
小结与适用边界
useZoomLevel的语义由内置参考文档 useZoomLevel.md 完整定义:无参读取/控制、传数值立即初始化、传 ref 双向同步,四组重载覆盖“默认帧/显式帧 × 初始值/源状态”的全部组合;- 使用前提是 Electron 渲染进程环境,且未显式传入
webFrame时需要nodeIntegration; - 按 AIRI 技能表的
EXTERNAL约定,需先安装@vueuse/electron才能启用;AIRI 桌面端的 Electron 版本约束可参照内部包@proj-airi/electron-vueuse的 peer 依赖>=39 <44; - 需要精确百分比缩放开,可改用同系列的
useZoomFactor,两者共享同一套调用约定。
【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考