首页 / Wails 入门教程 / 应用选项 Options

Wails 入门教程

应用选项 Options

本教程共 42 篇 · 第 8 篇 · 更新于 2026-08-03

Wailsoptions.App窗口配置生命周期日志

8. 应用选项 Options

本节目标

  • 知道 options.App 里最常用的窗口、资产、日志、生命周期字段
  • 会设置窗口尺寸、是否可缩放、是否置顶
  • 理解四个生命周期回调分别在什么时机触发
  • 知道 Bind、日志级别、调试开关怎么配

8-1 options.App 是什么

wails.Run(&options.App{...}) 里传的这个结构体,就是应用运行时的总配置。它和上一章的 wails.json 分工明确:wails.json 管”命令行怎么把项目编出来”,options.App 管”程序跑起来时长什么样、怎么反应”。窗口大小、资产从哪来、日志打多细、Go 方法绑哪些、调试开不开,全在这。

先给一份把常用字段都摆上的例子,后面逐个讲:

err := wails.Run(&options.App{
	Title:           "我的工具",
	Width:           1024,
	Height:          768,
	MinWidth:        800,
	MinHeight:       600,
	DisableResize:   false,
	WindowStartState: options.Normal,
	AssetServer: &assetserver.Options{
		Assets: assets,
	},
	LogLevel:  logger.INFO,
	OnStartup: app.startup,
	OnDomReady: app.domReady,
	OnShutdown: app.shutdown,
	OnBeforeClose: app.beforeClose,
	Bind: []interface{}{app},
	Debug: &options.Debug{
		OpenInspectorOnStartup: false,
	},
})

8-2 窗口与外观字段

Title:窗口标题栏文字。

Width / Height:初始窗口尺寸,单位像素。

MinWidth / MinHeight / MaxWidth / MaxHeight:窗口可缩放的上下限。不设就跟着系统默认走。限制范围能避免界面被拉到乱糟糟。

DisableResize:设为 true 后窗口不能拖大拖小,变成固定尺寸。做登录框、弹窗式工具时常这么干。

WindowStartState:窗口启动时的状态,取值有 options.Normal(正常)、options.Maximised(最大化)、options.Minimised(最小化)、options.Fullscreen(全屏)。

AlwaysOnTop:窗口始终浮在其他窗口上面。做悬浮计时器、录屏工具栏时有用。

BackgroundColour:窗口背景色,格式是 RGBA,比如 &options.RGBA{R: 0, G: 0, B: 0, A: 255}。做透明/异形窗口时会动到它。

Frameless:无边框模式,去掉系统自带的标题栏和边框,自己用 HTML/CSS 画标题栏。配合 CSSDragProperty 指定哪类元素可拖拽窗口。无边框窗口专门有一章讲,这里先知道有这个开关。

Tip

想让界面某块区域能拖整个窗口(无边框模式必备),用 CSSDragProperty + CSSDragValue 告诉 Wails 哪种 CSS 属性(如 --wails-drag 设为 drag)代表可拖拽区,前端给元素加上对应样式即可。

8-3 资产服务 AssetServer

AssetServer 决定前端界面从哪来。正常运行时它指向 //go:embed 编进来的 embed.FS

AssetServer: &assetserver.Options{
	Assets: assets,
},

assets 就是 main.go 顶部的 //go:embed all:frontend/dist 声明的那个变量。开发模式下 Wails 会自动把来源切到 Vite 服务器,你不用管。AssetServer 还能挂一个 Handler,用来动态返回文件或拦截请求——这正是第 11 章动态资产要展开的内容,这里先记住它的本职是”喂界面资源”。

8-4 日志 Logger / LogLevel

Logger:自定义日志输出器,实现 logger.Logger 接口即可。一般不用管,用默认。

LogLevel:日志级别,取值 logger.DEBUG / INFO / WARNING / ERROR / FATAL / SILENT。开发时设 DEBUG 看最细,发布设 INFO 或更高。Go 侧用 ctx 拿到的 runtime 日志会按这个级别过滤。

LogLevel: logger.INFO,
Note

这里的日志级别只管 Wails 框架和 Go 侧通过它打印的日志,不替你的前端 console.log 管。前端日志还是看浏览器 devtools(第 6 章的 wails dev -browser)。

8-5 四个生命周期回调

这是 options.App 里最高频用的一组,时机各不相同:

OnStartup:应用启动、窗口还没建好时触发,入参是 context.Context。你在这里把 ctx 存进结构体,后面调用运行时 API 全靠它。绑定的方法此时还没法被前端调(界面还没 ready)。

OnDomReady:前端 DOM 加载完成、界面真正可用后触发。需要启动时给前端推初始数据,放这里最稳——此时前端已经能接收了。

OnShutdown:应用退出前触发。做资源释放、保存配置、关连接放这里。

OnBeforeClose:用户点关闭按钮、窗口即将关时触发。返回 true 允许关闭,返回 false 拦下(比如弹个”确定退出吗”)。做退出确认、最小化到托盘不退出这类行为靠它。

func (a *App) beforeClose(ctx context.Context) bool {
	// 返回 false 阻止关闭,实现"关闭到托盘"
	return true
}

8-6 绑定、调试与其他

Bind:把结构体实例挂上来,它的公开方法才能被前端调用。第 12 章细讲,记住类型是 []interface{},放实例不放类型。

EnumBind:v2 里绑定枚举类型用。普通业务少见,需要把 Go 的枚举暴露给前端时配上。

ErrorFormatter:自定义 Go 方法返回 error 时,前端收到的错误长什么样。默认是一个标准格式,想改错误结构就实现这个函数。

Debug:调试选项。最常用的是 OpenInspectorOnStartup,设为 true 后应用启动自动打开 devtools 面板(相当于带着 -devtools 构建)。开发期排查界面问题很方便。

SingleInstanceLock:单实例锁,设为字符串锁名后,重复启动第二个实例会被拦下,参数还能转给第一个实例。防止程序多开的一章会专门讲。

DragAndDrop:开启文件拖放支持,让用户把文件拖进窗口。拖放专章会展开。

Warning

OnBeforeClose 返回 false 只是拦下”关闭动作”,不是退出程序。如果你在里面什么都不做又返回 false,用户会感觉”关不掉”。要实现”关到托盘”,得配合 HideWindowOnClose 或自己控制窗口显隐,逻辑要想清楚再写。

8-7 平台子选项 Windows / Mac / Linux

options.App 顶层是跨平台通用的,但有些外观行为各系统叫法不同,所以还有 WindowsMacLinux 三个子选项分别定制。比如 Mac 下能设 TitleBar 控制标题栏样式、Appearance 控制浅色或深色;Windows 下能设 WebviewTransparent 让 WebView 透明、ZoomFactor 调缩放;Linux 下能设 Icon 指定窗口图标。

大部分工具类应用用顶层字段就够了,要做贴近原生的精细外观时再钻进对应的子选项。这些平台差异项会在后面”窗口配置”相关章节细讲,这里先知道有这层结构:通用行为放顶层,平台特有问题放各自子选项,不要为了迁就某个系统把配置写在错误的地方。

常见误区

窗口尺寸设了却没生效。检查是不是 DisableResize 或某种窗口状态(如全屏)覆盖了你的预期;另外高分屏缩放也会让”看起来”尺寸不对,那是用 dpi 的事,不是配置错。

OnStartup 里就给前端推数据,结果前端没收到。此时界面还没 ready,推了也接不住。初始数据放 OnDomReady

把敏感逻辑只靠 OnBeforeClose 兜底保存。用户可能用任务管理器强杀,回调根本不触发。重要数据要定时存或实时存,别全押在退出那一刻。

小结

options.App 是运行时配置中枢:窗口尺寸/缩放/置顶在 Width/MinWidth/DisableResize/AlwaysOnTop;界面来源靠 AssetServer;日志看 LogLevel;四个生命周期 OnStartup/OnDomReady/OnShutdown/OnBeforeClose 管时机;Bind 暴露方法、Debug 开检查器。记住它管”运行时”,和管”构建”的 wails.json 是两套。下一章看前端到底是怎么被 Wails 接进来的。