做一个go的基于webassembly前端框架

原创
04/20 17:02
阅读数 270

花了些时间,学Xi了go,比较容易上手,顺手做了个webassembly框架,go语言加上极少量js,完成类似blazor,vue,react功能(不敢跟这些框架比😃)

为什么选go?

  1. JS下已经有大量牛X的框架,不做这类轮子,有需求的话直接拿来用
  2. C#有牛X的Blazor
  3. C/C++?算了。。。。
  4. RUST,这东西太牛X了,我入门了几次,写个链表直接挂了,不玩了
  5. Python,也能写webassembly,试了一下,光下载运行时就让人吐血,算了吧
  6. go好像有个vugu,但好像没人用

也只有go足够简单容易上手,自己写个玩玩吧。先上个效果图:

通过go实现webassembly框架。生成wasm文件3.56M(太大了?得了吧,现在什么时候了,这几M都舍不得?小姐姐大不大?)

这是全部代码,非常少:

已实现内置组件包括:

  1. sh-var 渲染指定名称的值,可以是变量也可以是go函数
  2. sh-if 根据指定的bool变量,动态渲染其中的内容,check目标可以是变量,也可以是go函数
  3. sh-list 根据指定的列表,动态渲染列表项。列表类型应是 []any ,以承载所有数据类型
  4. sh-body 渲染嵌套在组件标签内的子元素
  5. 事件绑定。@开头的事件,视为go事件绑定,调用指定的go 函数。如 @click="OnClick"
  6. 属性绑定。:开头的属性,将动态绑定到go的变量或函数

其他所有更复杂的组件,都可以通过以上几个基本组件完成。

示例中的app组件代码:

package demo

import (
	"fmt"
	cmpt "shwasm/cmpt"
	"time"
)

type appData struct {
	cmpt.CmptData //所有组件,应扩展自 CmptData

	message  string   //文本消息
	count    int      //点击数
	Ok       bool     //bool值,控制组件的一个开关
	DataList []any    //列表,应是 []any 类型,以承载所有类型的数据
	colors   []string //颜色清单,用于动态修改样式
}

// 当前时间
func (this *appData) Now() string {
	return time.Now().Format("2006-01-02 15:04:05")
}

func (this *appData) NotOk() bool {
	return !this.Ok
}

// 鼠标点击事件
func (this *appData) OnClick() {
	this.count++
	this.Ok = !this.Ok
	this.DataList = this.DataList[1:]
	this.DataList = append(this.DataList, fmt.Sprintf("New item_%v", this.count))
	this.GetInst().Refresh()
}

// 文本颜色,这个函数返回的是style值,将绑定到style属性
// 每次组件更新,循环切换颜色
func (this *appData) TextColor() string {
	index := this.count % 4
	color := this.colors[index]
	return "color:" + color
}

// 初始化函数
func NewAppData() *appData {
	return &appData{
		message:  "Hello from App",
		count:    1,
		Ok:       true,
		DataList: []any{"Item1", "item2", "Item3", "Item4"},
		colors:   []string{"#ff0000", "#00ff00", "#0000ff", "#000000"},
	}
}

func TestCpn() {
	//组件定义,名称为 go-app
	cmpt.DefineCmpt("go-app", func() cmpt.ICmptData {
		//提供组件的核心实例
		return NewAppData()
	}).LoadTemplate("www/app.html") // 加载嵌入的静态资源模板

	//渲染app
	node := &cmpt.CmptNode{Tag: "go-app"} //直接生成个标签
	inst := cmpt.NewInst("go-app")        //生成实例
	inst.Load(node)                       //加载标签
	inst.AmountAt("app")                  //挂载到id为app的div下
}

app 的 HTML模板

<div>
<h2 :style="TextColor">[<sh-var>message</sh-var>]</h2>
</div>
<hr />
<sh-if check="Ok">
    OK!(<sh-var>Now</sh-var>)
</sh-if>
<sh-if check="NotOk">
    Not OK!(<sh-var>Now</sh-var>)
</sh-if>
<hr />
(<sh-var>Ok</sh-var>)
(<sh-var>DataList</sh-var>)<br/>
<ul>
<sh-list name="DataList"><li><sh-item></sh-item></li></sh-list>
</ul>
<span style="font-size:20px;">Count: <sh-var>count</sh-var></span>
<button @click="OnClick">测试按钮</button>

目前已经实现最基本的功能,不过还相当的简陋,不敢放出代码来😃😃😃

主要是想通过这个项目来练手,快速上手go语言。做的过程中,也突然够白,为什么Blazor渲染的结果中,充斥着大量空注释 <!-- -->,它们不会被渲染出任何内容,但可以起到相当重要的作用:可以作为渲染HTML的插入点!!!

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
打赏
1 评论
0 收藏
0
分享
返回顶部
顶部