AIRI 项目 VueUse 指南:用 useZoomLevel 在 Electron 桌面端响应式控制窗口缩放级别
2026/9/10 16:23:30 网站建设 项目流程

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

FunctionDescriptionInvocation
useZoomLevelReactive WebFrame zoom levelEXTERNAL

这意味着在 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>refshallowRef或普通数值均可)作为源状态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.251.5)而非缩放级别(离散整数)。级别适合表达“放大一级/缩小一级”的步进语义(Ctrl++/ Ctrl+-快捷键),因子适合表达精确的百分比缩放,两者可以按1.2 ** level互相换算。

关键前提与注意事项

  1. nodeIntegration 前提:文档中的注释明确指出,若不显式传入webFrame,需要开启nodeIntegration。在强调安全性的生产应用中,更推荐的做法是通过webPreferences/ preload 拿到目标WebFrame实例后显式传入,从而避免依赖渲染进程的全局 Node 能力。
  2. 仅限 Electron 环境useZoomLevel依赖 Electron 的WebFrameAPI,在纯浏览器页面(如 AIRI 的 Web 端)中不存在对应能力,只能在 Electron 渲染进程中运行。
  3. 依赖前提:该函数来自独立包@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 列出mousewindow boundsauto 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询