Wails 开发参考字典:常用 API 速查

使用说明

本字典整理 Wails v2 日常开发最常查的 API,版本锚点是 v2.9.2(2024 年 11 月时点的 v2 最新稳定版,v3 尚在 alpha,未收录)。Go 侧条目全部来自 github.com/wailsapp/wails/v2/pkg/runtime 包,前端条目来自 CLI 生成的 wailsjs/runtime 模块(同一套函数也挂在 window.runtime 上)。条目按”签名 → 什么时候用 → 最小示例 → 坑”组织,示例自包含可复制,这里只做查与抄,原理讲解看《Wails 框架要点》。

一、Go 侧运行时 API

组内共性:所有函数第一个参数都是 ctx context.Context——就是 OnStartup 回调里那个,丢了它所有运行时调用都不生效。易混点集中在事件家族:Emit 是发,On 是收,Off 是按名解绑,Once 是收一次就解绑。

EventsEmit

func EventsEmit(ctx context.Context, eventName string, optionalData ...interface{})

向所有事件监听方广播一条事件,载荷跟在事件名后,数量不限。给前端推进度、状态变更用它。

runtime.EventsEmit(a.ctx, "download:progress", file, done, total)

⚠️ OnDomReady 之前 emit,前端监听器还没注册,事件直接丢。初始状态用绑定方法拉取,事件只做增量通知。

EventsOn

func EventsOn(ctx context.Context, eventName string, callback func(optionalData ...interface{})) func()

Go 侧订阅事件(多为前端发来的),返回值是取消函数,调它即解绑。与 JS 侧同名函数行为一致。

off := runtime.EventsOn(a.ctx, "ui:filter", func(optionalData ...interface{}) {
    // JSON 边界:JS 发来的数字一律是 float64,断言 int 会失败
    keyword, _ := optionalData[0].(string)
    _ = keyword
})

⚠️ 载荷是 []interface{},数字是 float64、字符串才是 string;高频数据别走事件,走绑定方法,事件通道没有回执。

EventsOnce 与 EventsOnMultiple

func EventsOnce(ctx context.Context, eventName string, callback func(...interface{})) func()
func EventsOnMultiple(ctx context.Context, eventName string, callback func(...interface{}), counter int) func()

Once 触发一次自动解绑;OnMultiple 限定最多触发 counter 次。适合”初始化完成即失效”的一次性握手。

⚠️ Once 的回调里如果再注册同名监听,注意解绑时机,避免前一次的残留监听还在收。

EventsOff 与 EventsOffAll

func EventsOff(ctx context.Context, eventName string, additionalEventNames ...string)
func EventsOffAll(ctx context.Context)

按名批量解绑;OffAll 清空全部监听,页面整体刷新前用。

⚠️ 优先用 EventsOn 返回的取消函数精确解绑;Off 是按事件名一刀切,会把同名的其他监听一起干掉。

ClipboardGetText 与 ClipboardSetText

func ClipboardGetText(ctx context.Context) (string, error)
func ClipboardSetText(ctx context.Context, text string) error

读、写系统剪贴板的纯文本。做剪贴板类工具、把导出结果一键塞进剪贴板都用它。

text, err := runtime.ClipboardGetText(a.ctx)
if err != nil {
    // 剪贴板里可能是图片等非文本内容,按错误处理而不是当空串
    runtime.LogDebug(a.ctx, "clipboard not text")
}

⚠️ 剪贴板内容可能是图片、文件等非文本对象,GetText 会返回错误而不是空串,别把错误当”剪贴板为空”吞掉。

OpenFileDialog 与 SaveFileDialog

func OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)
func SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error)

单选文件打开框、保存框。OpenDialogOptions 常用字段:DefaultDirectory、DefaultFilename、Title、Filters([]FileFilter,按 DisplayName/Pattern 过滤)。多选与目录用 OpenMultipleFilesDialog / OpenDirectoryDialog。

path, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
    DefaultFilename: "export.json",
    Title:           "保存导出文件",
})

⚠️ 用户取消选择时返回空串与 nil error,两个返回值都要判:只判 err 不判空串,后面拿空路径去写文件必炸。

MessageDialog

func MessageDialog(ctx context.Context, dialogOptions MessageDialogOptions) (string, error)

原生消息框,替代网页 alert——生产构建里没有浏览器弹窗能力,系统级确认框用它。Type 常量有 InfoDialog / WarningDialog / ErrorDialog / QuestionDialog;Buttons 自定义按钮文字,返回点中的按钮文字。

choice, _ := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
    Type:    runtime.QuestionDialog,
    Title:   "清空历史",
    Message: "确定要清空全部记录吗?",
    Buttons: []string{"确定", "取消"},
})
if choice != "确定" {
    return nil
}

⚠️ 返回值是按钮文字字符串,改了 Buttons 数组记得同步改判断,最好用常量。

BrowserOpenURL

func BrowserOpenURL(ctx context.Context, url string)

用系统默认浏览器打开链接,而不是在 WebView 里导航走——”关于页”、”帮助文档”这类外部链接的规范出口。

⚠️ 让 WebView 内部导航到外部网站会把应用变成”浏览器”,且脱离了应用上下文;外部 URL 一律走这个函数。

日志家族:LogTrace / LogDebug / LogInfo / LogWarning / LogError / LogFatal

runtime.LogInfo(a.ctx, "config loaded")

分级日志,dev 模式打到控制台。LogFatal 记录后直接终止进程,只用于”活不下去”的启动失败。

⚠️ LogFatal 在绑定方法里等于”点一下按钮应用就退”,绑定方法里的失败应该走 error 返回值。

Environment

func Environment(ctx context.Context) EnvironmentInfo // BuildType / Platform / Arch

BuildType 取值 “dev” 或 “production”,用来在运行时开关调试行为;Platform/Arch 打日志定位用户环境。

⚠️ BuildType 是编译期决定的运行时事实,不要用它做需要编译期裁剪的事(那该用 build tag)。

Show、Hide 与 Quit

func Show(ctx context.Context)
func Hide(ctx context.Context)
func Quit(ctx context.Context)

显示/隐藏窗口(常驻应用的核心组合)、退出应用。配合 HideWindowOnClose 选项做”点关闭只是藏起来”。

⚠️ Hide 之后用户没有任何入口唤回(v2 没有系统托盘),要么留绑定按钮,要么用 SingleInstanceLock 让二次启动唤回主窗口。

OnFileDrop

func OnFileDrop(ctx context.Context, callback func(x, y int, paths []string))
func OnFileDropOff(ctx context.Context)

接收文件拖入,回调拿到落点坐标与绝对路径列表。需在 options.App 里配 DragAndDrop: &options.DragAndDrop{EnableFileDrop: true}(v2.9.0 起提供)。

⚠️ 不配 DragAndDrop 选项时回调永远不触发;WebView 自己的 drop 行为想关掉用 DisableWebViewDrop,否则拖图进窗口会当资源打开。

窗口函数速记

WindowSetSize / WindowGetSize / WindowSetPosition / WindowGetPosition / WindowSetMinSize / WindowSetMaxSize / WindowCenter / WindowShow / WindowHide / WindowMaximise / WindowUnminimise / WindowSetAlwaysOnTop / WindowSetTitle / WindowFullscreen——签名统一是 func WindowXxx(ctx context.Context, ...),Get 类返回值。窗口置顶常驻小面板的用法:runtime.WindowSetAlwaysOnTop(a.ctx, true)。

⚠️ v2 是单窗口模型,这些函数都作用于唯一主窗口;WindowSetAlwaysOnTop 是 v2.6.0 起的能力,更早版本没有。

二、options.App 关键字段

组内共性:全部在 wails.Run(&options.App{...}) 里一次性传入,运行时改不了。易混点:StartHidden 是”启动时藏”,HideWindowOnClose 是”点关闭改藏”,两个是不同行为。

字段 类型与语义 什么时候用
Bind []interface{},要暴露给前端的结构体实例 几乎所有应用必配
AssetServer *assetserver.Options,Assets 指内嵌 fs.FS 单文件产物的基础,配合 go:embed
OnStartup / OnDomReady / OnBeforeClose / OnShutdown 生命周期回调 存 ctx / 发首屏事件 / 拦截关闭 / 清理
StartHidden bool,启动时不显示窗口 常驻工具的静默启动
HideWindowOnClose bool,点关闭改为隐藏 常驻应用替代 OnBeforeClose 拦截
WindowStartState options.Normal / Maximised / Minimised / Fullscreen 控制初始窗口状态
AlwaysOnTop bool,窗口置顶 小面板、悬浮工具
SingleInstanceLock *options.SingleInstanceLock,单实例锁(v2.7.0+) 防止多开;二次启动唤回主窗口
DragAndDrop *options.DragAndDrop,文件拖入(v2.9.0+) 接收文件路径的应用
EnableDefaultContextMenu bool,生产构建启用默认右键菜单 需要”复制粘贴”右键操作时

Bind 展开示例

app := NewApp()
Bind: []interface{}{app}, // 换行写在 options.App 里;绑定的实例方法均暴露

⚠️ 绑定的是实例:同一个结构体 New 两份、只绑了一份,另一份的状态前端永远看不到,症状是”方法能调但字段都是零值”。

SingleInstanceLock 展开示例

SingleInstanceLock: &options.SingleInstanceLock{
    UniqueId: "e8f2b3c0-7d1a-4b9e-9c3f-demo-app-uuid", // 用 UUID,全局唯一
    OnSecondInstanceLaunch: app.onSecondInstanceLaunch,
},

// 第二次双击 exe 时走到这里:唤起已存在的主窗口
func (a *App) onSecondInstanceLaunch(data options.SecondInstanceData) {
    runtime.WindowUnminimise(a.ctx)
    runtime.Show(a.ctx)
}

⚠️ 官方文档明确:该回调不会自动聚焦窗口,必须自己调 WindowUnminimise + Show;且从第二实例传来的参数按不可信输入对待。Linux 上窗口管理器可能拒绝抢焦点,这是平台行为不是 bug。

三、前端 JS 运行时

组内共性:import 自 wailsjs/runtime(CLI 生成),也全局挂在 window.runtime 上;与 Go 侧同名函数语义一致,只是没有 ctx 参数。

EventsOn(JS 侧)

import { EventsOn, EventsEmit, EventsOff } from '../wailsjs/runtime';

// 返回取消函数,组件卸载时调用,防止监听越积越多
const off = EventsOn('download:progress', (file, done, total) => {
  bar.style.width = (done / total) * 100 + '%';
});
EventsEmit('ui:filter', 'invoice'); // 前端也能发,Go 侧 EventsOn 收

⚠️ 最常见的内存泄漏来源:组件每次挂载都 EventsOn、从不解绑,同一事件收到 N 次回调。取消函数要么存起来在卸载时调,要么用 EventsOff 按名清理。

ClipboardGetText 与 ClipboardSetText(JS 侧)

import { ClipboardSetText } from '../wailsjs/runtime';

const ok = await ClipboardSetText('已复制的文本');

⚠️ 这套函数走的是 Wails 的运行时通道,与浏览器 navigator.clipboard 的权限模型无关;但在 WebView 里 navigator.clipboard 常受限制,要稳定读写优先用 runtime 版。

其他 JS 侧函数

WindowSetTitle / WindowCenter / WindowFullscreen / WindowSetSize 等窗口组、LogInfo 等日志组、BrowserOpenURL、ScreenGetAll、Quit / Show / Hide、Environment——全部与 Go 侧同名同语义。要在”非绑定场景”(如模板事件)里快速用就用 window.runtime.xxx。

⚠️ JS 侧没有对话框函数:文件选择、消息确认在 v2 里只有 Go 侧 runtime.Dialog 系列能做,封装成绑定方法给前端调。

四、CLI 与项目配置

组内共性:命令都不钉版本号(@latest 或项目内固定版本);wails.json 是 CLI 与项目构建的单一事实来源,手写 npm 命令绕过它迟早出构建顺序问题。

命令 一句话用途 常用参数
wails init 从模板生成项目 -n 项目名,-t 模板(vue-ts/react-ts/svelte-ts/vanilla 等)
wails dev 开发模式:热更新 + 生成绑定 -browser 用浏览器开调试页
wails build 生产构建,产出单文件可执行程序 -platform 目标平台,-tags 追加构建标签
wails doctor 体检平台依赖是否齐全 装完环境先跑一次
wails generate module 重新生成 wailsjs 绑定模块 绑定类型报错时刷新
wails update 升级 CLI 不钉版本号,升级前看 changelog
wails.json 字段 一句话用途 有什么坑
frontend:install 构建前安装前端依赖的命令 改了包管理器(pnpm/yarn)要同步改这里
frontend:build wails build 时构建前端产物的命令 产物没进 dist 目录时 embed 会编译失败
wailsjsdir 自动生成绑定模块的输出目录 默认在项目根 wailsjs,前端 import 路径以此为锚
outputfilename 二进制产物文件名 Windows 产物自动加 .exe
devServer dev 服务器地址,默认 localhost:34115 端口被占时浏览器调试页起不来
assetdir dev 模式静态资产目录 与 AssetServer.Assets 是两套事:前者 dev 用,后者打进二进制

速查表

条目 一句话用途 有什么坑
EventsEmit 广播事件给前端 DomReady 前发等于白发
EventsOn 订阅事件,返回取消函数 JS 数字到 Go 是 float64
EventsOnce 订阅一次即解绑 适合握手,别做常驻监听
EventsOff 按名批量解绑 会误杀同名的其他监听
ClipboardGetText / SetText 读写剪贴板文本 非文本内容返回 error 不是空串
OpenFileDialog / SaveFileDialog 文件选择框 取消时是空串 + nil error
MessageDialog 原生消息/确认框 返回值是按钮文字字符串
BrowserOpenURL 系统浏览器打开链接 别让 WebView 导航去外站
Log 家族 分级日志 LogFatal 会直接退出进程
Environment dev/production 与平台信息 运行时事实,别当编译期开关
Show / Hide / Quit 窗口显隐与退出 Hide 后要有唤回入口
OnFileDrop 接收文件拖入 必须先配 DragAndDrop 选项
WindowSetAlwaysOnTop 窗口置顶(v2.6.0+) v2 单窗口,只作用于主窗口
Bind 暴露 Go 结构体方法给前端 绑实例不是绑类型
AssetServer.Assets 内嵌前端资产 dist 为空编译失败
HideWindowOnClose 点关闭改为隐藏 与 OnBeforeClose 拦截二选一
SingleInstanceLock 单实例锁 + 二次启动回调(v2.7.0+) 回调不自动聚焦,要手动 Show
DragAndDrop 选项 启用文件拖入(v2.9.0+) 不开 EnableFileDrop 拖入无回调
JS EventsOn 前端订阅事件 不解绑是泄漏源头
wails dev / build 开发热更新 / 生产单文件产物 改前端必须重新 build 才进产物
wails generate module 重新生成 wailsjs 绑定 类型对不上时先跑它

相关阅读:安装与第一个窗口见《Wails 入门》;绑定与事件的原理展开见《Wails 框架要点》;这些 API 组合起来能做什么,看实战篇《用 Wails 做一个剪贴板历史工具》。Go 侧函数的签名风格(ctx 第一参、多返回值、error 收尾)是标准 Go 惯例,不熟悉的先补《Go内置函数详解》。

版本核实(以官方文档为准):本字典基于 Wails v2.9.2(2024 年 11 月时点的 v2 最新稳定版)核对,含 v2.7.0 起的 SingleInstanceLock、v2.9.0 起的 DragAndDrop、v2.6.0 起的 WindowSetAlwaysOnTop 等版本敏感条目;各签名以 GitHub 仓库 v2.9.2 标签源码与 wails.io 文档为准。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇