高级用法
IPC 双向通信
火山 → 前端
发送IPC消息 把 payload 推给指定窗口,前端用 jade.on 接收:
Jade.发送IPC消息 (主窗口ID, "state-changed", "{\"count\":42}")jade.on('state-changed', payload => {
const data = typeof payload === 'string' ? JSON.parse(payload) : payload;
console.log(data.count);
});推送复杂数据时用内置 json_object 构造,避免手拼转义:
变量 消息 <类型 = json_object>
消息.置文本 ("level", "success")
消息.置文本 ("message", "任务完成")
Jade.发送IPC消息 (主窗口ID, "toast", 消息.到文本 ())前端 → 火山
前端 jade.invoke(通道, payload) 返回 Promise;火山侧回调返回非空文本即应答,空文本不回传:
const res = await jade.invoke('query-user', { id: 1001 }, { timeout: 8000 });如果 (通道名 == "query-user")
{
变量 请求 <类型 = json_object>
请求.创建自文本 (数据)
变量 应答 <类型 = json_object>
应答.置整数 ("id", 请求.取整数 ("id", 0))
应答.置文本 ("name", "张三")
返回 (应答.到文本 ())
}回调线程与耗时操作
IPC 回调与部分事件回调可能来自库的工作线程。回调里不要做长耗时阻塞操作(前端 invoke 会超时),更不要弹同步对话框——需要对话框用 _异步 版本;重活交给线程后台做,完成后用 发送IPC消息 推结果。
前端资源加载三方案
| 方案 | 调用 | 适用 |
|---|---|---|
| 本地目录 | 置协议服务目录 (取运行目录 () + "web", 热载) | 开发期 / 资源不敏感 |
| 磁盘 JAPK | 置协议服务目录 ("app.japk", 假) | 资源打包但随文件分发 |
| 内存 JAPK | 应用包.加载字节集 (...) 后 置协议服务目录 ("") | 资源加密 + 磁盘零前端文件 |
三种方式返回的地址都直接传给 创建窗口,与库同源、IPC 无跨域问题。
跨域与 IPC 风险
页面若从外部 http(s):// 域加载,jade.invoke 受 源站白名单(JadeViewOptions)约束——不设白名单时外部源无法与宿主通信。协议服务加载的本地页面不受此限制。
JAPK 资源包详解
JAPK 是 JadeView 的前端资源加密 / 签名包格式。内存加载流程:
// 1.(签名包)设置 Ed25519 公钥——设置后只接受签名包
Jade.应用包.设置公钥 ("base64公钥44字符")
// 2. 从字节集加载(也可用 加载视窗文件资源 直接读内嵌资源,实现单 exe 全内置)
变量 结果 <类型 = 整数>
结果 = Jade.应用包.加载字节集 (读入文件 ("app.japk"))
如果 (结果 != 0)
{
调试输出 ("JAPK 加载失败, 错误码:", 结果) // 负数错误码,详见 API 参考
}
// 3. 根目录留空 = 服务已加载的内存包,返回 JADE://<应用标识>
变量 地址 <类型 = 文本型>
地址 = Jade.置协议服务目录 ("")注意事项:
- JAPK 打包时的应用名 / 应用标识必须与
初始化传入的一致(错配返回-6) - 加载失败详情也会经
应用包加载失败事件回报 - 免费版打包的 JAPK 应使用「填路径」方式(
置协议服务目录 ("app.japk")),而非字节集内存加载 - 把
.japk作为视窗文件资源内嵌后用加载视窗文件资源,可实现前端资源完全藏进 exe
单实例与协议唤起
初始化 开启单实例后,用户再次启动 exe(含 myapp:// 协议唤起),第二个进程会把完整命令行转发给首实例并退出,首实例收到 第二实例 事件:
// 注册自定义协议(写注册表)
Jade.系统.注册协议 ("myapp")方法 JadeView_第二实例 <接收事件 类型 = 整数>
参数 来源对象 <类型 = JadeView>
参数 标记值 <类型 = 整数>
参数 窗口ID <类型 = 整数>
参数 数据 <类型 = 文本型>
参数 命令行参数 <类型 = 文本数组类>
{
如果 (来源对象 == Jade)
{
// 唤起主窗口;命令行参数 已自动排除 argv[0] 的 exe 路径
Jade.窗口.置可视 (主窗口ID, 真)
Jade.窗口.置焦点 (主窗口ID)
}
返回 (0)
}窗口材质(Windows 11)
Mica / Acrylic 材质由 DWM 在窗口层渲染,前提是:
窗口选项.透明窗口 = 真- 页面
body背景透明(CSSbackground: transparent),否则页面底色盖住材质 - 仅 Windows 11 可用——用
Jade.系统.是否为Win11()判断后降级为置背景色纯色底
如果真 (Jade.系统.是否为Win11 ())
{
Jade.窗口.置材质 (窗口ID, 窗口材质.云母)
}INFO
页面里的浮层(下拉、Toast)如果用半透明背景 + backdrop-filter,在透明窗口上会直接透到桌面——backdrop-filter 只能模糊页面内像素,够不着 DWM 材质层。浮层请用不透明底色。
标题栏方案对比
| 边框风格 | 标题栏 | 控制按钮 | 拖动 |
|---|---|---|---|
普通窗口 | 系统标题栏 | 系统 | 系统 |
标题覆盖 | 无标题栏,页面顶到边 | 库内置(右上角,置标题栏覆盖层样式 可调配色) | 页面标记 jade-region-drag |
无标题栏 / 无边框 | 无 | 前端自绘(经 IPC 调 最小化 / 最大化切换 / 关闭) | 页面标记 jade-region-drag |
页面拖动区用 HTML 布尔属性标记(运行时自动注入,无需 JS):
<header jade-region-drag>
标题栏内容……
<button jade-region-no-drag>可点击的按钮(挖洞)</button>
</header>与旧 CSS -webkit-app-region: drag 的区别:右键不弹系统标题栏菜单。
多线程注意事项
- JadeView 的 API 函数是线程安全的,可从火山工作线程调用
- 事件 / IPC 回调可能来自库线程:回调里操作你自己的共享数据需自行加锁
- 回调内避免阻塞(见上文 IPC 一节)
打包与分发
- 静态链接,产物单 exe;前端资源经
@视窗.附属文件复制或 JAPK 内置 - 运行时依赖仅 WebView2 Runtime(Win11 自带;Win10 检测安装见官方 WebView2 安装指南)
- 数据目录默认在
%LOCALAPPDATA%下按应用标识划分,日志在{数据目录}\logs(路径常量.应用日志目录)