14 KiB
v3的更改
!!! note这是当前的无序更改脑升级。很快它将组织成一个更易读的格式。
选项
自v2以来,应用程序选项已经进行了修订。
事件
在v3中,有3种类型的事件:
- 应用程序事件
- 窗口事件
- 自定义事件
应用程序事件
应用程序事件是由应用程序发出的事件。这些事件包括macOS上
的ApplicationDidFinishLaunching
等本机事件。
窗口事件
窗口事件是由窗口发出的事件。这些事件包括macOS上的WindowDidBecomeMain
等本机事
件。还定义了常见事件,以便它们在跨平台上工作,例如WindowClosing
。
自定义事件
用户定义的事件称为WailsEvents
。这是为了将它们与用于与浏览器通信的Event
对象区
分开来。WailsEvents现在是封装事件的对象。这包括事件名称,数据和事件的源。
与WailsEvent关联的数据现在是单个值。如果需要多个值,则可以使用struct。
事件回调和Emit
函数签名
事件回调的签名(由On
,Once
和OnMultiple
使用)已更改。在v2中,回调函数接收可
选数据。在v3中,回调函数接收包含与事件相关的所有数据的WailsEvent
对象。
类似地,Emit
函数已更改。它现在不再接受名称和可选数据,而是接受一
个WailsEvent
对象,它将发出该对象。
Off
和OffAll
在v2中,Off
和OffAll
调用将删除JS和Go中的事件。由于v3具有多窗口的特性,因此已
更改为这些方法仅适用于调用它们的上下文。例如,如果你在一个窗口中调用Off
,它仅
会删除该窗口的事件。如果你在Go中使用Off
,它只会删除Go的事件。
Hooks
事件钩子是v3中的新功能。它们允许您钩入事件系统,并在发出某些事件时执行操作。例
如,您可以钩入WindowClosing
事件,在窗口关闭之前执行一些清理操作。钩子可以在应
用程序级别或窗口级别使用RegisterHook
进行注册。应用程序级别适用于应用程序事件。
仅当窗口级别钩子与其注册的窗口一起调用。
日志记录
在v2中,日志记录会混淆,因为应用程序日志和系统(内部)日志都使用相同的记录器。我 们已经对此进行了简化:
- 内部日志现在使用标准的Go
slog
记录器处理。这是通过应用程序选项中的logger
选 项进行配置的。默认情况下,这使用tint记录 器。 - 现在可以通过新的
log
插件进行应用程序日志记录,它在底层使用slog
。此插件提供 了一个简单的用于记录到控制台的API。它在Go和JS中都可用。
开发人员注意事项
在Go中发出事件时,它会将事件分派到本地的Go侦听器以及应用程序中的每个窗口。在JS中 发出事件时,它现在会将事件发送到应用程序。这将被处理,就好像它是在Go中发出的,但 是发送者ID将是窗口的ID。
窗口
Window API在很大程度上保持不变,但方法现在是在窗口实例而不是运行时上。一些值得注 意的变化是:
- 窗口现在具有标识它们的名称。用于在发出事件时标识窗口。
- 窗口上现在有更多以前不可用的方法,例如
AbsolutePosition
和ToggleDevTools
。 - 窗口现在可以通过本机拖放接受文件。有关详细信息,请参阅拖放部分。
剪切板
剪贴板API已经简化。现在有一个单独的Clipboard
对象,可以用于读取和写入剪贴
板。Clipboard
对象在Go和JS中都可用。SetText()
用于设置文本,Text()
用于获取文
本。
绑定
绑定的工作方式与v2类似,通过提供一种将结构方法绑定到前端的方式。这些可以在前端使
用由wails3 generate bindings
命令生成的绑定包装器来调用:
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import { main } from "./models";
window.go = window.go || {};
window.go.main = {
GreetService: {
/**
* GreetService.Greet
* Greet greets a person
* @param name {string}
* @returns {Promise<string>}
**/
Greet: function (name) {
wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0));
},
/**
* GreetService.GreetPerson
* GreetPerson greets a person
* @param person {main.Person}
* @returns {Promise<string>}
**/
GreetPerson: function (person) {
wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0));
},
},
};
默认情况下,绑定的方法是混淆的,并使用uint32 ID进行标识,该ID是使
用FNV哈希算法计
算的。这是为了防止方法名称在生产构建中被暴露出来。在调试模式下,方法ID与计算的方
法ID一起记录,以帮助调试。如果您希望增加额外的混淆层,可以使用BindAliases
选
项。这允许您指定别名ID与方法ID的映射。当前端使用ID调用方法时,方法ID将首先在别名
映射中查找匹配项。如果找不到,它将假定是标准方法ID,并尝试以通常的方式查找方法。
示例:
app := application.New(application.Options{
Bind: []any{
&GreetService{},
},
BindAliases: map[uint32]uint32{
1: 1411160069,
2: 4021313248,
},
Assets: application.AssetOptions{
FS: assets,
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
现在我们可以使用此别名在前端调用:wails.Call(1, "world!")
。
不安全调用
如果您不介意在二进制文件中以明文形式提供调用,并且不打算使
用garble,那么可以使用不安全
的wails.CallByName()
方法。此方法接受要调用的方法的完全限定名称和要传递给它的参
数。示例:
```go
wails.CallByName("main.GreetService.Greet", "world!")
```
!!! danger
这仅作为开发的便利方法提供。不建议在生产中使用此方法。
对话框
对话框现在在JavaScript中可用!
Windows
Windows中的对话框按钮是不可配置的,根据对话框的类型是恒定的。要在按下按钮时触发
回调,请创建一个具有与您希望附加回调的按钮相同名称的按钮。示例:创建一个标签为“
确定”的按钮,并使用OnClick()
方法设置回调方法:
dialog := app.QuestionDialog().
SetTitle("Update").
SetMessage("The cancel button is selected when pressing escape")
ok := dialog.AddButton("Ok")
ok.OnClick(func() {
// Do something
})
no := dialog.AddButton("Cancel")
dialog.SetDefaultButton(ok)
dialog.SetCancelButton(no)
dialog.Show()
拖放
可以按窗口启用本机拖放。只需将EnableDragAndDrop
窗口配置选项设置为true
,窗口
将允许将文件拖放到其上。当这种情况发生时,将发出events.FilesDropped
事件。然后
可以使用WindowEvent.Context()
中的DroppedFiles()
方法检索文件名。这将返回一个
包含文件名的字符串切片。
上下文菜单
上下文菜单是当用户右键单击元素时显示的上下文菜单。创建上下文菜单与创建标准菜单相
同,使用app.NewMenu()
。要使上下文菜单对窗口可用,请调
用window.RegisterContextMenu(name, menu)
。名称将是上下文菜单的ID,并由前端使
用。
要指示元素具有上下文菜单,请将data-contextmenu
属性添加到元素。此属性的值应为先
前在窗口中注册的上下文菜单的名称。
可以在应用程序级别注册上下文菜单,使其对所有窗口可用。可以使
用app.RegisterContextMenu(name, menu)
完成此操作。如果在窗口级别找不到上下文菜
单,则将检查应用程序上下文菜单。v3/examples/contextmenus
中可以找到此演示。
Wails标记语言(WML)
Wails标记语言是一种简单的标记语言,允许您在没有JavaScript的情况下向标准HTML元素 添加功能。
当前支持以下标签:
data-wml-event
这指定单击元素时将发出Wails事件。属性的值应为要发出的事件的名称。
示例:
<button data-wml-event="myevent">Click Me</button>
有时您需要用户确认操作。可以通过向元素添加data-wml-confirm
属性来完成。此属性的
值将是要显示给用户的消息。
示例:
<button data-wml-event="delete-all-items" data-wml-confirm="Are you sure?">
Delete All Items
</button>
data-wml-window
可以通过将data-wml-window
属性添加到元素中来调用任何wails.window
方法。属性的
值应为要调用的方法的名称。方法名称应与导出的方法的名称完全匹配。
<button data-wml-window="Close">Close Window</button>
data-wml-trigger
此属性指定应触发操作的javascript事件。默认为click
。
<button data-wml-event="hover-box" data-wml-trigger="mouseover">
Hover over me!
</button>
系统托盘
Wails 3附带了一个内置的系统托盘。这是一个完全功能的系统托盘,旨在尽可能简单地使 用。可以设置托盘的图标、工具提示和菜单。还可以“附加”窗口到系统托盘。这样做将提供 以下功能:
- 单击托盘图标会切换窗口可见性
- 右键单击托盘将打开菜单(如果有)
在macOS上,如果没有附加的窗口,则托盘将使用显示菜单的默认方法(任何按钮)。如果 有附加的窗口但没有菜单,则托盘将切换窗口,而不管按下的按钮如何。
插件
插件是扩展Wails应用程序功能的一种方式。
创建插件
插件是符合以下接口的标准Go结构:
type Plugin interface {
Name() string
Init(*application.App) error
Shutdown()
CallableByJS() []string
InjectJS() string
}
Name()
方法返回插件的名称。这用于记录目的。
Init(*application.App) error
方法在加载插件时调用。*application.App
参数是加载
插件的应用程序。任何错误都将阻止应用程序启动。
Shutdown()
方法在应用程序关闭时调用。
CallableByJS()
方法返回可以从前端调用的导出函数列表。这些方法名称必须与插件导出
的方法名称完全匹配。
InjectJS()
方法返回应注入到创建的所有窗口中的JavaScript。这对于添加与插件补充的
自定义JavaScript函数很有用。
提示
枚举
在Go中,枚举通常被定义为类型和一组常量。例如:
type MyEnum int
const (
MyEnumOne MyEnum = iota
MyEnumTwo
MyEnumThree
)
由于Go和JavaScript之间的不兼容性,无法以这种方式使用自定义类型。最好的策略是为 float64使用类型别名:
type MyEnum = float64
const (
MyEnumOne MyEnum = iota
MyEnumTwo
MyEnumThree
)
在Javascript中,您可以使用以下代码:
const MyEnum = {
MyEnumOne: 0,
MyEnumTwo: 1,
MyEnumThree: 2,
};
- 为什么使用
float64
?不能使用int
吗?- 因为JavaScript没有“int”的概念。一切都是
number
,在Go中会转换为float64
。Go 的反射包中还有类型转换的限制,这意味着使用int
是行不通的。
- 因为JavaScript没有“int”的概念。一切都是
BackgroundColour
在v2中,这是指向RGBA
结构的指针。在v3中,这是RGBA
结构的值。
WindowIsTranslucent
已删除此标志。现在有一个BackgroundType
标志,可用于设置窗口应具有的背景类型。此
标志可以设置为以下任何值:
BackgroundTypeSolid
- 窗口将具有实心背景BackgroundTypeTransparent
- 窗口将具有透明背景BackgroundTypeTranslucent
- 窗口将具有半透明背景
在Windows上,如果BackgroundType
设置为BackgroundTypeTranslucent
,则可以使
用WindowsWindow
选项中的BackdropType
标志设置透明度的类型。这可以设置为以下任
何值:
Auto
- 窗口将使用系统确定的效果None
- 窗口没有背景Mica
- 窗口使用Mica效果Acrylic
- 窗口使用丙烯酸效果Tabbed
- 窗口使用选项卡效果
Windows Application Options
WndProcInterceptor
如果设置了此标志,将拦截WndProc并调用该函数。这允许您直接处理Windows消息。该函数 应具有以下签名:
func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnValue uintptr, shouldReturn)
如果shouldReturn
值设置为true
,则returnValue
将由主wndProc方法返回。如果设置
为false
,将忽略返回值,并且消息将继续由主wndProc方法处理。
在关闭时隐藏窗口+OnBeforeClose
在v2中,有一个HideWindowOnClose
标志,用于在关闭窗口时隐藏窗
口。HideWindowOnClose
标志与OnBeforeClose
回调之间存在逻辑重叠。在v3中,已删
除HideWindowOnClose
标志,并将OnBeforeClose
回调重命名为ShouldClose
。当用户
尝试关闭窗口时,将调用ShouldClose
回调。如果回调返回true
,窗口将关闭。如果返
回false
,窗口将不会关闭。这可以用于隐藏窗口而不是关闭窗口。
窗口拖动
在v2中,使用--wails-drag
属性来指示可以使用元素拖动窗口。在v3中,已将其替换
为--webkit-app-region
,以更符合其他框架处理方式。--webkit-app-region
属性可以
设置为以下任何值:
drag
- 可使用该元素拖动窗口no-drag
- 该元素无法用于拖动窗口
我们本来希望使用app-region
,但是在webkit在macOS上的getComputedStyle
调用不支
持它。