跳到正文

视图

组件在挂载时构建界面。当子节点需要随状态出现、消失或重新排序时,使用 ui.Show 和 ui.For。

#视图如何工作

每个组件都返回 *ui.Element。用 .Child(...) 或 .Children(...) 传入子节点。多个兄弟节点可以返回 ui.Fragment(...),无需额外包裹。

func ViewExample() *ui.Element {
	return ui.View().Padding(20).Gap(12).Children(
		ui.Text("Hello from Go"),
		ui.Button().Child("Continue").OnClick(func() {}),
	)
}

普通的 Go if 或 for 只在构建组件时运行,之后不会再更新。

#条件内容

用 ui.Show 根据状态挂载或移除子节点。

func DisclosureExample() *ui.Element {
	open, setOpen := ui.CreateSignal(false)
	return ui.View().Children(
		ui.Button().Child("Toggle details").OnClick(func() { setOpen(!open()) }),
		ui.Show(
			open,
			func() *ui.Element { return ui.Text("Details") },
		),
	)
}

#列表

用 ui.For 渲染会变化的列表。给每一行稳定且唯一的 key——用数据库 ID,不要用下标。ui.KeyedFor 还会给行一个访问当前项的 accessor。

type ListPerson struct {
	ID   int
	Name string
}

func KeyedListExample() *ui.Element {
	people, setPeople := ui.CreateSignal([]ListPerson{{1, "Ada"}, {2, "Grace"}})
	return ui.View().Children(
		ui.Button().Child("Reorder and rename").OnClick(func() {
			setPeople([]ListPerson{{2, "Grace"}, {1, "Ada Lovelace"}})
		}),

		ui.KeyedFor(
			people,
			func(person ListPerson) any { return person.ID },
			func(person func() ListPerson, index func() int) *ui.Element {
				return ui.Text(
					index(),
					": ",
					person().Name,
				)
			},
			func() *ui.Element { return ui.Text("No people") },
		),
	)
}

编辑数据时传入新的切片。原地修改已存储的切片不会通知订阅者。长列表请使用 VirtualList 或 Table。

#窗口生命周期

每个窗口有自己的组件根。关闭窗口会释放它的界面和 effect。用 ui.OnCleanup 注册清理。ui.Async 在 UI goroutine 之外运行工作,把结果送回,并在组件消失时取消。

func LoadingPanel(load func(context.Context) (string, error)) *ui.Element {
	result, setResult := ui.CreateSignal("Loading…")
	ui.Async(
		load,
		func(value string, err error) {
			if err != nil {
				setResult(err.Error())
				return
			}
			setResult(value)
		},
	)
	return ui.Text(result())
}

#当前窗口

在组件挂载时捕获 native.CurrentWindow(),然后在回调里使用这个句柄。

func CloseButton() *ui.Element {
	window := native.CurrentWindow()
	return ui.Button().Child("Close window").OnClick(func() { window.Close() })
}

#测试

在应用模块中运行 quickgui test。quickgui fmt --check 检查格式。应用是 Go 可执行文件,因此常用的 Go 调试器和堆栈会指向你的源文件。