参考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) }) // 回到渲染线程,安全
}()
相关推荐
林壮Allen6 小时前
用 Go 从零实现多 Agent 协作框架:两个让我踩坑的设计问题
go·ai编程
代码方舟12 小时前
Go数据工程:利用天远柠檬查出险优化二手车批发拍卖车源出险核查合规体验
人工智能·go
不是万能的豆学长12 小时前
排查Go服务40天后的内存泄漏问题
开发语言·后端·golang·go
用户1257585243612 小时前
Golang后台管理框架推荐:XYGo Admin与devinggo怎么选?
后端·go·ai编程
tachibana214 小时前
Go语言里slice是怎么扩容的?
后端·golang·go·切片
tachibana21 天前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
newerp1 天前
GC Pacer 调优算法:GOGC、GOMEMLIMIT 与容器 OOM 防御
后端·程序员·go
newerp1 天前
逃逸分析、栈分配与 sync.Pool 对象池
后端·程序员·go
Laurie三省3 天前
现场版却配上录音室版的歌词?聊聊我给开源 Mac 歌词软件写的多源打分算法
算法·macos·go
newerp3 天前
Execution Trace 深入实战:可视化调度与系统停顿分析
后端·程序员·go