Files
wails3-nuxt4/MIGRATION_GUIDE.md
2026-03-11 18:33:15 +08:00

18 KiB
Raw Blame History

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.Serviceapplication.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() *WebviewWindow
  • Window.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 / PasswordAutosaveEnabled
  • WindowDidMoveDebounceMS / ResizeDebounceMS

新增 LinuxWindow 结构体:

Linux: application.LinuxWindow{
    Icon:                []byte{},
    WindowIsTranslucent: false,
    WebviewGpuPolicy:    application.WebviewGpuPolicyOnDemand,
    Menu:                myMenu,
    MenuStyle:           application.LinuxMenuStylePrimaryMenu,
},

迁移建议: 无需修改。可利用 HideOnFocusLostHideOnEscape 简化你的系统托盘窗口逻辑。


5. events.Common.WindowClosingRegisterHook

状态: 完全相同,无变更

你的当前代码:

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.AssetOptionsAssetFileServerFS

状态: 完全兼容(新增 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,
},

新增平台支持

  • iOSIOSOptions 包含 WebView 偏好、原生标签栏等
  • AndroidAndroidOptions 包含 WebView 配置

迁移步骤

  1. 更新依赖版本:

    go get github.com/wailsapp/wails/v3@v3.0.0-alpha.74
    go mod tidy
    
  2. 编译测试:

    go build .
    
  3. 检查 app.Event.Emit() 是否编译通过。 如果失败,尝试:

    • 使用 app.EmitEvent(name, data...)
    • 查看 EventManager 的最新方法列表
  4. 可选优化:

    • 使用 systray.AttachWindow(mainWindow) 替代手动托盘-窗口切换逻辑
    • 考虑使用 BundledAssetFileServer 替代 AssetFileServerFS
    • 利用 WebviewWindowOptions.HideOnEscapeHideOnFocusLost 简化窗口行为
    • 实现 ServiceShutdown() 接口处理优雅关闭
  5. 更新前端绑定:

    # 如果使用 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() 兼容 无需修改