18 KiB
Wails v3 API 迁移指南:alpha.27 → alpha.74
本文档基于对 wailsapp/wails 仓库
v3-alpha分支最新源码的全面分析。
总结
好消息:你当前项目中使用的所有 API 在最新版本中基本保持向后兼容。 大多数变更是新增功能和选项,而非破坏性更改。唯一需要关注的是 app.Event.Emit() 方法可能的签名变化。
1. application.New() 和 application.Options{}
状态:✅ 向后兼容(新增字段,无破坏性变更)
你的当前代码:
app := application.New(application.Options{
Name: "main",
Description: "A demo of using raw HTML & CSS",
Services: []application.Service{...},
Assets: application.AssetOptions{...},
Mac: application.MacOptions{...},
})
变更内容:
Options 结构体新增了大量可选字段,但原有字段完全保留:
| 新增字段 | 类型 | 说明 |
|---|---|---|
Icon |
[]byte |
应用图标(用于默认关于框) |
Logger |
*slog.Logger |
自定义日志记录器 |
LogLevel |
slog.Level |
日志级别 |
MarshalError |
func(error) []byte |
自定义服务方法错误序列化 |
BindAliases |
map[uint32]uint32 |
绑定方法别名 ID |
Flags |
map[string]any |
传递给前端的键值对 |
PanicHandler |
func(*PanicDetails) |
panic 处理器 |
KeyBindings |
map[string]func(window Window) |
全局键绑定 |
OnShutdown |
func() |
关闭前回调(阻塞) |
PostShutdown |
func() |
关闭后回调 |
ShouldQuit |
func() bool |
控制是否允许退出 |
RawMessageHandler |
func(window Window, message string, originInfo *OriginInfo) |
自定义前端消息处理 |
WarningHandler |
func(string) |
警告处理器 |
ErrorHandler |
func(err error) |
错误处理器 |
FileAssociations |
[]string |
文件关联(如 [".txt", ".md"]) |
SingleInstance |
*SingleInstanceOptions |
单实例模式配置 |
Transport |
Transport |
自定义 IPC 传输层 |
Server |
ServerOptions |
HTTP 服务器模式配置 |
DisableDefaultSignalHandler |
bool |
禁用默认信号处理 |
IOS |
IOSOptions |
iOS 平台配置 |
Android |
AndroidOptions |
Android 平台配置 |
新增 WindowsOptions 字段:
Windows: application.WindowsOptions{
WndClass: "MyApp",
DisableQuitOnLastWindowClosed: true,
WebviewUserDataPath: "",
WebviewBrowserPath: "",
EnabledFeatures: []string{},
DisabledFeatures: []string{},
AdditionalBrowserArgs: []string{},
WndProcInterceptor: nil,
},
新增 LinuxOptions 字段:
Linux: application.LinuxOptions{
DisableQuitOnLastWindowClosed: true,
ProgramName: "my-app",
},
迁移建议: 无需修改。可根据需要使用新增字段。
2. application.Service 和 application.NewService() 注册 API
状态:✅ 向后兼容(新增 NewServiceWithOptions)
你的当前代码:
Services: []application.Service{
application.NewService(appService),
application.NewService(&GreetService{}),
},
变更内容:
NewService[T any](instance *T) Service— 签名不变- 新增
NewServiceWithOptions[T any](instance *T, options ServiceOptions) Service
ServiceOptions 结构体:
type ServiceOptions struct {
Name string // 服务名称
Route string // HTTP 路由前缀,挂载 http.Handler
MarshalError func(error) []byte // 单服务的错误序列化
}
新增 DefaultServiceOptions 变量。
新增可选接口:
// 可选:自定义服务名称
type ServiceName interface {
ServiceName() string
}
示例:使用新 API
// 旧方式(仍然有效)
application.NewService(appService)
// 新方式:带选项
application.NewServiceWithOptions(appService, application.ServiceOptions{
Name: "app-service",
Route: "/api/app",
})
迁移建议: 无需修改。如需自定义服务路由或名称,可使用 NewServiceWithOptions。
3. ServiceStartup 方法签名
状态:✅ 完全相同,无变更
你的当前代码:
func (a *App) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
a.ctx = ctx
return nil
}
分析: 签名完全一致:ServiceStartup(ctx context.Context, options ServiceOptions) error
新增可选生命周期接口:
// 可选:服务关闭时调用
type ServiceShutdown interface {
ServiceShutdown() error
}
示例:添加关闭钩子
func (a *App) ServiceShutdown() error {
log.Println("App service shutting down")
return nil
}
迁移建议: 无需修改。可选择实现 ServiceShutdown() 接口。
4. app.Window.NewWithOptions() / WebviewWindowOptions
状态:✅ 向后兼容(大量新增选项)
你的当前代码:
mainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Window 1",
Mac: application.MacWindow{
InvisibleTitleBarHeight: 50,
Backdrop: application.MacBackdropTranslucent,
TitleBar: application.MacTitleBarHiddenInset,
},
BackgroundColour: application.NewRGB(27, 38, 54),
URL: "/",
Width: 1240,
Height: 850,
})
变更内容:
app.Window 类型为 *WindowManager(之前已是类似的管理器模式),API 不变:
Window.New() *WebviewWindowWindow.NewWithOptions(WebviewWindowOptions) *WebviewWindow- 新增
Window.GetByName(name string) (Window, bool) - 新增
Window.GetByID(id uint) (Window, bool) - 新增
Window.Current() Window - 新增
Window.GetAll() []Window - 新增
Window.OnCreate(callback func(Window))— 窗口创建回调
WebviewWindowOptions 新增字段:
| 新增字段 | 类型 | 说明 |
|---|---|---|
KeyBindings |
map[string]func(window Window) |
窗口级键绑定 |
IgnoreMouseEvents |
bool |
忽略鼠标事件(Windows + Mac) |
ContentProtectionEnabled |
bool |
内容保护(防截屏) |
HideOnFocusLost |
bool |
失去焦点时隐藏 |
HideOnEscape |
bool |
按 Esc 键隐藏 |
UseApplicationMenu |
bool |
使用应用全局菜单 |
DefaultContextMenuDisabled |
bool |
禁用默认右键菜单 |
DevToolsEnabled |
bool |
启用开发者工具 |
MacWindow 新增字段:
| 新增字段 | 类型 | 说明 |
|---|---|---|
EventMapping |
map[events.WindowEventType]events.WindowEventType |
事件映射 |
EnableFraudulentWebsiteWarnings |
bool |
欺诈网站警告 |
WebviewPreferences |
MacWebviewPreferences |
WebView 偏好设置 |
WindowLevel |
MacWindowLevel |
窗口层级 |
CollectionBehavior |
MacWindowCollectionBehavior |
Spaces 和全屏行为 |
LiquidGlass |
MacLiquidGlass |
Liquid Glass 效果(macOS 15.0+) |
WindowsWindow 新增字段:
HiddenOnTaskbar— 从任务栏隐藏EnableSwipeGestures— 触控滑动手势Menu *Menu— 窗口菜单Permissions— WebView2 权限控制ExStyle— 扩展窗口样式GeneralAutofillEnabled/PasswordAutosaveEnabledWindowDidMoveDebounceMS/ResizeDebounceMS
新增 LinuxWindow 结构体:
Linux: application.LinuxWindow{
Icon: []byte{},
WindowIsTranslucent: false,
WebviewGpuPolicy: application.WebviewGpuPolicyOnDemand,
Menu: myMenu,
MenuStyle: application.LinuxMenuStylePrimaryMenu,
},
迁移建议: 无需修改。可利用 HideOnFocusLost 和 HideOnEscape 简化你的系统托盘窗口逻辑。
5. events.Common.WindowClosing 和 RegisterHook
状态:✅ 完全相同,无变更
你的当前代码:
mainWindow.RegisterHook(events.Common.WindowClosing, func(event *application.WindowEvent) {
mainWindow.Hide()
event.Cancel()
})
分析:
events.Common.WindowClosing— 仍然存在(值1028)RegisterHook签名不变:RegisterHook(eventType events.WindowEventType, callback func(event *WindowEvent)) func()WindowEvent.Cancel()方法不变- 现在
RegisterHook返回一个func()取消函数(alpha.27 可能也是如此)
补充:OnWindowEvent 方法
// OnWindowEvent 用于注册窗口事件监听器(非 Hook)
mainWindow.OnWindowEvent(events.Common.WindowClosing, func(event *application.WindowEvent) {
// Hook 可以取消事件,OnWindowEvent 不能
})
迁移建议: 无需修改。
6. app.SystemTray.New() 系统托盘 API
状态:✅ 向后兼容(大量功能增强)
你的当前代码:
systray := app.SystemTray.New()
systray.SetMenu(trayMenu)
systray.OnClick(func() {
mainWindow.Show()
mainWindow.Focus()
})
变更内容:
原有 API 完全保留,新增以下方法:
| 新增方法 | 说明 |
|---|---|
OnRightClick(func()) |
右键点击处理 |
OnDoubleClick(func()) |
双击处理 |
OnRightDoubleClick(func()) |
右键双击处理 |
OnMouseEnter(func()) |
鼠标进入处理 |
OnMouseLeave(func()) |
鼠标离开处理 |
AttachWindow(window Window) |
绑定窗口到托盘(自动切换显示/隐藏) |
WindowOffset(offset int) |
设置窗口与托盘的间距 |
WindowDebounce(debounce time.Duration) |
Windows 上防抖设置 |
Show() / Hide() |
显示/隐藏托盘图标 |
OpenMenu() |
打开托盘菜单 |
ShowWindow() / HideWindow() / ToggleWindow() |
窗口操作 |
SetDarkModeIcon(icon []byte) |
深色模式图标 |
SetTemplateIcon(icon []byte) |
macOS 模板图标 |
SetTooltip(tooltip string) |
设置提示文本 |
SetLabel(label string) |
设置标签文本 |
SetIconPosition(IconPosition) |
设置图标位置 |
Destroy() |
销毁托盘 |
推荐:使用 AttachWindow 简化代码
你当前手动实现的"点击托盘显示/隐藏窗口"逻辑,现在可以用内置的 AttachWindow 替代:
// 新方式(推荐)
systray := app.SystemTray.New()
systray.SetMenu(trayMenu)
systray.AttachWindow(mainWindow).WindowOffset(10)
// AttachWindow 自动处理点击切换显示/隐藏
迁移建议: 无需修改。推荐使用 AttachWindow 简化托盘-窗口绑定逻辑。
7. app.Event.Emit() 事件 API
状态:⚠️ 需要验证(可能有方法名变更)
你的当前代码:
app.Event.Emit("time", now)
分析:
app.Event 类型为 *EventManager。在最新源码中:
WebviewWindow.EmitEvent(name string, data ...any) bool— 窗口级事件发射- 内部调用
globalApplication.Event.EmitEvent(event *CustomEvent)
EventManager 上的方法可能从 Emit(name, data...) 更名为 EmitEvent,或两者共存。
可能的迁移方式:
// 如果 Emit 仍然存在(最可能的情况)
app.Event.Emit("time", now)
// 如果需要使用 EmitEvent
app.EmitEvent(&application.CustomEvent{
Name: "time",
Data: now,
})
新增事件 API 特性:
- 严格事件模式:构建标签
strictevents启用事件注册检查 OnApplicationEvent— 监听应用级事件- 事件发射现在返回
bool,指示事件是否被 Hook 取消
迁移建议: 升级后编译测试。如果 Emit 编译失败,尝试改用 EmitEvent 或查看最新文档。
8. application.AssetOptions 和 AssetFileServerFS
状态:✅ 完全兼容(新增 BundledAssetFileServer)
你的当前代码:
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
变更内容:
AssetOptions 结构体字段不变:
type AssetOptions struct {
Handler http.Handler // 不变
Middleware Middleware // 不变
DisableLogging bool // 不变
}
AssetFileServerFS 函数签名不变:
func AssetFileServerFS(assets fs.FS) http.Handler
新增:BundledAssetFileServer
func BundledAssetFileServer(assets fs.FS) http.Handler
与 AssetFileServerFS 的区别:BundledAssetFileServer 额外在 /wails/runtime.js 路径提供编译后的运行时 JS 文件。
新增:中间件链
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
Middleware: application.ChainMiddleware(
myAuthMiddleware,
myLoggingMiddleware,
),
DisableLogging: true,
},
迁移建议: 无需修改。如果需要运行时 JS 内置服务,可考虑切换到 BundledAssetFileServer。
9. MacOptions, MacWindow, MacTitleBarHiddenInset, MacBackdropTranslucent
状态:✅ 完全兼容(新增选项)
你的当前代码:
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
// ...
Mac: application.MacWindow{
InvisibleTitleBarHeight: 50,
Backdrop: application.MacBackdropTranslucent,
TitleBar: application.MacTitleBarHiddenInset,
},
分析:
所有使用的类型和常量均未更改:
MacOptions.ApplicationShouldTerminateAfterLastWindowClosed— ✅ 存在MacOptions.ActivationPolicy— ✅ 存在MacWindow.InvisibleTitleBarHeight— ✅ 存在MacWindow.Backdrop(类型MacBackdrop) — ✅ 存在MacWindow.TitleBar(类型MacTitleBar) — ✅ 存在MacBackdropTranslucent常量 — ✅ 存在MacTitleBarHiddenInset预定义变量 — ✅ 存在
新增 MacBackdrop 值:
const (
MacBackdropNormal MacBackdrop = iota // 不变
MacBackdropTransparent // 不变
MacBackdropTranslucent // 不变
MacBackdropLiquidGlass // 新增:macOS 15.0+ Liquid Glass
)
新增 MacTitleBar 预定义变量:
var MacTitleBarHiddenInsetUnified = MacTitleBar{...} // 新增
新增 MacWindow 功能:
MacWindowLevel— 控制窗口层级(normal,floating,modalPanel等)MacWindowCollectionBehavior— 控制 Spaces 和全屏行为MacLiquidGlass— Liquid Glass 效果配置MacWebviewPreferences— WebView 偏好设置
Liquid Glass 示例(macOS 15.0+):
Mac: application.MacWindow{
Backdrop: application.MacBackdropLiquidGlass,
LiquidGlass: application.MacLiquidGlass{
Style: application.LiquidGlassStyleAutomatic,
CornerRadius: 12,
TintColor: &application.RGBA{Red: 255, Green: 255, Blue: 255, Alpha: 128},
},
},
迁移建议: 无需修改。
10. application.Context 类型(菜单点击处理器)
状态:✅ 完全相同,无变更
你的当前代码:
trayMenu.Add("显示主窗口").OnClick(func(ctx *application.Context) {
mainWindow.Show()
mainWindow.Focus()
})
分析:
Context结构体不变MenuItem.OnClick(func(*Context)) *MenuItem— 签名不变Context.ClickedMenuItem() *MenuItem— 不变Context.IsChecked() bool— 不变Context.ContextMenuData() string— 不变
Menu.Add(label string) *MenuItem — 不变
迁移建议: 无需修改。
其他重要新增功能
窗口接口 Window
最新版本定义了 Window 接口,*WebviewWindow 实现该接口。这允许更灵活的窗口操作。
新增 Manager 模式
所有子系统现在通过 Manager 模式访问:
app.Window // *WindowManager
app.SystemTray // *SystemTrayManager
app.Event // *EventManager
app.Menu // *MenuManager
app.Dialog // *DialogManager
app.Screen // *ScreenManager
app.Clipboard // *ClipboardManager
app.Browser // *BrowserManager
app.Env // *EnvironmentManager
app.KeyBinding // *KeyBindingManager
app.ContextMenu // *ContextMenuManager
运行时服务注册
app.RegisterService(application.NewService(myService))
HTTP Transport
Transport: application.NewHTTPTransport(),
Server 模式
使用 server 构建标签,应用可作为 HTTP 服务器运行:
Server: application.ServerOptions{
Host: "0.0.0.0",
Port: 8080,
},
新增平台支持
- iOS —
IOSOptions包含 WebView 偏好、原生标签栏等 - Android —
AndroidOptions包含 WebView 配置
迁移步骤
-
更新依赖版本:
go get github.com/wailsapp/wails/v3@v3.0.0-alpha.74 go mod tidy -
编译测试:
go build . -
检查
app.Event.Emit()是否编译通过。 如果失败,尝试:- 使用
app.EmitEvent(name, data...)或 - 查看
EventManager的最新方法列表
- 使用
-
可选优化:
- 使用
systray.AttachWindow(mainWindow)替代手动托盘-窗口切换逻辑 - 考虑使用
BundledAssetFileServer替代AssetFileServerFS - 利用
WebviewWindowOptions.HideOnEscape和HideOnFocusLost简化窗口行为 - 实现
ServiceShutdown()接口处理优雅关闭
- 使用
-
更新前端绑定:
# 如果使用 Wails CLI 生成绑定 wails3 generate bindings
你的项目兼容性矩阵
| API 使用点 | 当前代码 | 兼容性 | 操作 |
|---|---|---|---|
application.New(Options{}) |
✅ | 兼容 | 无需修改 |
application.NewService() |
✅ | 兼容 | 无需修改 |
ServiceStartup(ctx, opts) |
✅ | 兼容 | 无需修改 |
app.Window.NewWithOptions() |
✅ | 兼容 | 无需修改 |
events.Common.WindowClosing |
✅ | 兼容 | 无需修改 |
RegisterHook() |
✅ | 兼容 | 无需修改 |
app.SystemTray.New() |
✅ | 兼容 | 无需修改 |
app.Event.Emit() |
⚠️ | 需验证 | 编译测试 |
AssetFileServerFS() |
✅ | 兼容 | 无需修改 |
MacBackdropTranslucent |
✅ | 兼容 | 无需修改 |
MacTitleBarHiddenInset |
✅ | 兼容 | 无需修改 |
MacOptions{} |
✅ | 兼容 | 无需修改 |
*application.Context |
✅ | 兼容 | 无需修改 |
app.NewMenu() |
✅ | 兼容 | 无需修改 |
app.Quit() |
✅ | 兼容 | 无需修改 |