跳到正文

组件

编写一个返回 *ui.Element 的函数。从 View、Text 和 Button 开始,其余控件也用同样的方式组合。

#定义组件

传入普通的 Go 值。如果参数读取了信号,函数返回后绑定仍然有效,不需要额外标注。

func CounterLabel(count int) *ui.Element {
	return ui.Text("Count: ", count).FontSize(20)
}

func ComponentExample() *ui.Element {
	count, setCount := ui.CreateSignal(0)
	return ui.View().Children(
		CounterLabel(count()),
		ui.Button().Child("Increment").OnClick(func() { setCount(count() + 1) }),
	)
}

结构体也一样。更新 quantity 会改变文本;LineItem 保持挂载。

type Product struct {
	ID    string
	Name  string
	Price int
}

func LineItem(product Product, quantity int) *ui.Element {
	return ui.Text(product.Name, " × ", quantity, " = $", product.Price*quantity)
}

func Cart() *ui.Element {
	quantity, setQuantity := ui.CreateSignal(1)
	return ui.View().Children(
		LineItem(Product{ID: "mug", Name: "Mug", Price: 12}, quantity()),
		ui.Button().Child("Add one").OnClick(func() { setQuantity(quantity() + 1) }),
	)
}

用 ui.View() 创建容器,再用 .Child(...) 或 .Children(...) 追加内容。

func CardComponent(title string, children ...any) *ui.Element {
	return ui.View().FlexCol().Padding(20).Gap(12).Children(
		ui.Text(title).FontWeight(600),
		children,
	)
}

#基础组件

View、Text、Button 和 Input 覆盖大多数布局和文本。在同一个元素上链式调用样式、属性和事件。

可选的 extensions/editor 软件包提供 Rust 核心的 Editor、CodeBlock 与 DiffView,无需 CGO 或另一份原生库。

可选的 extensions/markdown 软件包提供保留式 Markdown,包括流式协调和 CodeBlock 渲染。

func ButtonExample(save func()) *ui.Element {
	return ui.Button().Child("Save changes").
		Height(40).
		PaddingLeft(16).
		PaddingRight(16).
		BackgroundColor("#2563eb").
		TextColor("white").
		BorderRadius(8).
		Hover(func(s ui.StyleBuilder) ui.StyleBuilder { return s.BackgroundColor("#3b82f6") }).
		OnClick(save)
}

#复合组件

先创建实例,再组合它的具名部件。字符串可以直接作为子节点。

func TabsExample() *ui.Element {
	tabs := ui.NewTabs().DefaultValue("account")
	return tabs.Root().Children(
		tabs.List().Children(
			tabs.Tab("account").Child("Account"),
			tabs.Tab("security").Child("Security"),
		),
		tabs.Panel("account").Child("Account settings"),
		tabs.Panel("security").Child("Security settings"),
	)
}

在实例上配置行为,在部件上设置样式。部件可以像普通子节点一样嵌套。

#受控状态

传入当前值,并在变更回调里写入下一个值。在拥有它的组件内部创建实例。

func CheckboxExample() *ui.Element {
	checked, setChecked := ui.CreateSignal(false)
	checkbox := ui.NewCheckbox().Checked(checked()).OnCheckedChange(
		func(next bool, _ *native.Event) { setChecked(next) },
	)
	return checkbox.Root().FlexRow().Gap(8).Children(
		checkbox.Indicator().Child("✓"),
		"Remember me",
	)
}

#组件类别

组件参考 覆盖表单、浮层、菜单、表格、树等。可从本仓库运行示例:

bun packages/cli/src/cli.ts dev --project examples/components

#设置各部件的样式

直接给部件设置样式,或共享一个 ui.Style() 值:

triggerStyle := ui.Style().Padding(12).RoundedLg().Bg("#2563eb")
return popover.Trigger().Style(triggerStyle).TextColor("#ffffff").Child("Account")

添加 OnClick 仍会保留部件的默认动作。需要取消时,在 OnClickEvent 上调用 PreventDefault()。