参考react 实现一个golang gui

看到yoga 布局引擎,让我有个想法实现一个golang gui。 下面就是我的思路实现

Tenon

Go 语言的声明式、React 风格 GUI 工具包 ------ 函数组件 + Hooks,基于 Yoga flex 布局与 Gio 渲染。


把 React 的模型带到 Go 原生 GUI:

  • 函数组件 + Hooks ------ UseState/UseEffect/UseReducer/UseMemo/UseCallback/UseRef/UseContext。无 class、无手动失效。
  • 自动、局部重渲染 ------ setter 只重渲染它所属的组件(fiber)。
  • HTML 风格元素 ------ Div/Span/Button/Input/Img/Text/ScrollView/Portal/Fragment
  • Yoga flex 布局,Gio 渲染(GPU 加速的矢量路径与文字;抗锯齿、高分屏自适应)。
  • 开箱即用 ------ 动画(补间/进出场/FLIP)、变换、拖拽/悬停/键盘,基础组件 kit,以及一套 shadcn/ui 风格组件库(~41 个)。

内部是类 React 的三棵树:不可变 Node 描述 → 持久 Fiber(身份 + hooks)→ renderNode(yoga 节点 + 绘制)。布局增量:纯绘制更新不重算布局。

快速上手

bash 复制代码
go get github.com/sjm1327605995/tenon
go 复制代码
package main

import (
	"fmt"
	ui "github.com/sjm1327605995/tenon/pkg/ui"
)

func Counter(_ struct{}) *ui.Node {
	count, setCount := ui.UseState(0)
	return ui.Div(
		ui.Style(ui.Row, ui.Gap(16), ui.Padding(24), ui.ItemsCenter),
		ui.Button(ui.OnClick(func() { setCount(count - 1) }), ui.Text("-")),
		ui.Text(fmt.Sprintf("%d", count), ui.FontSize(32)),
		ui.Button(ui.OnClick(func() { setCount(count + 1) }), ui.Text("+")),
	)
}

func main() { ui.Run(ui.Use(Counter, struct{}{})) }

包结构

说明
pkg/ui 引擎 + 元素、Hooks、样式、动画、输入。
pkg/shadcn 基于 pkg/ui 的 shadcn/ui 风格组件库(Button/Card/Dialog/Select/Table/Toast...)。
pkg/router 栈式导航(具名路由 + 参数,Push/Pop/Replace、返回)------ React Navigation 风格,纯建立在 hooks 之上。
yoga 纯 Go 的 Yoga flex 布局引擎移植。
pkg/font 字体加载/测量(内置支持 CJK 的字体)。

示例

  • go run ./example/accordion ------ 一个 shadcn/ui 风格的小型 文档站 。左侧分组侧栏列出 17 个组件(点击切换);右侧是该组件的文档页(面包屑、标题栏、框架标签、实时可交互预览、安装区),放在 ScrollView 里、各区块随滚动淡入;底部开关切换明暗主题。
  • go run ./example/router ------ 用 pkg/router 做的 栈式导航 :一个收件箱,点邮件 Push 进详情屏;详情屏可 Pop 返回,并用 Replace 原地换成下一封而不加深栈。

后台更新

渲染是单线程的。后台 goroutine 里更新界面请用 ui.Post 包裹:

go 复制代码
go func() {
	data := fetch()
	ui.Post(func() { setData(data) }) // 回到渲染线程,安全
}()
相关推荐
newerp9 小时前
Golang 切片扩容策略
后端·程序员·go
我的div丢了肿么办9 小时前
go中make声明切片, 修改切片,append给切片扩容,合并切片,复制切片
后端·go
纪卓志George10 小时前
保守十四年:Go 的泛型方法与丢失的定位
go
运维开发笔记11 小时前
8.3 Go Struct 嵌入学习笔记
go
xiangjiaodalishi11 小时前
2026年GEO生成式引擎优化服务商观察:企业如何挑选适配自身的AI营销协作伙伴
go
蛋先生DX11 小时前
明明都是源码到CPU,各语言中间原理咋不是一个套路?
java·javascript·go
西瓜太郎4991 天前
从请求到上游:实现一条可观测的多模型调用链
go
newerp1 天前
Golang 切片底层结构
后端·程序员·go
运维开发笔记2 天前
8.2 Go Struct 方法学习笔记
go
Go_error2 天前
Fyne:让 Go 开发者也能玩转 GUI
后端·go