go 前端框架 vecty 學習

gopherjs 是把 go 編譯爲 js 的工具。 vecty 是基於 gopherjs 的一種相似 React 的開發框架。javascript

安裝 gopherjs 和 vecty

go get -u github.com/gopherjs/gopherjs
go get -u github.com/gopherjs/vecty

vecty 自帶的例子在 example 目錄,有 todomvc 和 markdown 編輯器。java

簡單的例子

package main

import (
	"strconv"

	v "github.com/gopherjs/vecty"
	"github.com/gopherjs/vecty/elem"
	"github.com/gopherjs/vecty/event"
)

func main() {
	v.SetTitle("title message swt")
	v.RenderBody(&MyComponent{})
}

type MyComponent struct {
	v.Core
	btnCount int
}

func (mc *MyComponent) onButtonClick(e *v.Event) {
	println("click my component button")
	mc.btnCount++
	v.Rerender(mc)
}

func (mc *MyComponent) Render() v.ComponentOrHTML {
	return elem.Body(
		elem.Button(
			v.Markup(
				event.Click(mc.onButtonClick),
			),
			v.Text("btn"+strconv.Itoa(mc.btnCount)),
		),
	)
}

運行它

在 $GOPATH/src/ele/gopherjs/t1 文件寫下這個文件,命名爲 t1.go。而後 cd 到 t1 文件夾,運行命令 gopherjs serve,將會在 localhost:8080 運行服務,使用瀏覽器訪問 http://localhost:8080/ ,則能夠查看運行結果。node

解釋

這個例子中,定義了組件 MyComponent,須要內嵌 vecty.Core 結構,實現 vecty.Component 接口要求的 Render 方法。git

Render 方法負責構建表明組件的 HTML。github

再看 main 方法,調用 vecty.SetTitle 方法設置標題,調用 vecty.RenderBody(&MyComponent{}) 方法把 MyCompoent 組件渲染爲文檔的 body。瀏覽器

回到 MyComponent 的 Render 方法,在 Button 內包含 Markup, Markup 內包括 event.Click,給 Button 附加了 click 事件處理函數 onButtonClick。markdown

事件處理函數 onButtonClick 修改了此組件的 btnCount 字段,而後調用 vecty.Rerender 方法從新渲染此組件,界面上就能看到按鈕上的文字被改變了。mvc

定義組件結構

type Comp1 struct {
	v.Core
	A int `vecty:"prop"`
}

加上 vecty:"prop" 纔是一個合格的組件屬性。若是不給 A 字段加這個 tag,那麼在 Comp1 的上級組件被從新渲染時,就不會考慮 Comp1 的 A 屬性值,就認爲 Comp1 沒有任何改變,不會從新渲染 Comp1,不會改變 Comp1 的 HTML,不會調用 Comp1 的 Rerender 方法。框架

若是給 A 字段加上這個 tag,那麼在 Comp1 的上級被從新渲染時,就會考慮 Comp1 的 A 的值,與以前的 Comp1 的 A 值對比,若是不一樣,則認爲須要從新渲染 Comp1。dom

引用底層的 javascript 元素

在事件處理函數中引用組件渲染出的某個 javascript 節點

例子

type AddTodoView struct {
	v.Core
	store vstore.Store
}

func (atv *AddTodoView) Render() v.ComponentOrHTML {
	input := elem.Input()
	return elem.Div(
		elem.Form(
			v.Markup(
				event.Submit(func(e *v.Event) {
				}).PreventDefault(),
			),

			input,
			elem.Button(
				v.Markup(
					prop.Type("submit"),
					event.Click(func(e *v.Event) {
						println("btn click")
						node := input.Node()
						value := strings.TrimSpace(node.Get("value").String())
						if value != "" {
							atv.store.Dispatch(addTodo(value))
							node.Set("value", "")
						}
					}),
				),

				v.Text("Add Todo"),
			),
		),
	)
}

以上代碼中,爲了簡單,直接把按鈕的 click 事件處理函數定義在組件的 Render 方法中,在事件處理函數內引用了外部變量 input,調用它的 Node 方法獲取底層的輸入框 javascript 對象,類型爲 *js.Object,就能直接對輸入框進行操做,好比獲取輸入框的內容和清空輸入框內容。

相關文章
相關標籤/搜索