Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Happy-Ferret/go-vdom-wasm

Open more actions menu
 
 

Repository files navigation

go-vdom-wasm

This package allows to build frontend applications in Go targeting Webassembly. It provides a conveniant syntax close to the hyperscript one in the JavaScript lands and aims to provide efficient way to deal with the DOM. If you're not familiar the Virtual DOM notion, I suggest you take a look at this document.

⚠️ This package is not production ready. Use at your own risks. A Todos section is available if you want to take part of the projet and try to make it better. You can also check the Go + WASM wiki to get a better overview of the Webassembly support for the Go language.

This module has been inspired by the awesome work of @mbasso on https://github.com/mbasso/asm-dom.

Want to see go-vdom-wasm in action?

Ready to start?

Before starting

You have to make some little configuration that are well explained in the Go + WASM wiki - Getting started guide.

If you prefer a quickest solution, you can also rely on the go-wasm-cli utility. It allows to create a WASM application in one command line and to have hot reload while coding.

Install the module

In your favorite terminal

$ GOOS=js GOARCH=wasm go get github.com/mfrachet/go-vdom-wasm

Usage

Let's define the root of our go-vdom-wasm application. Everything that the library will work on is inside that div:

<!-- index.html-->

<div id="app"></div>

Let's now Patch that node with a virtual one to make something happen:

// main.go

rootNode := vn.H("div", "Hello world")

vn.Patch("#app", rootNode)

Passing attributes

In this example, we set a class="navbar" to the underlying ul element

vn.H("ul", &vn.Props{"class": "navbar"}, vn.Children{
	vn.H("li", "First item"),
	vn.H("li", "Second item"),
}),

The DOM representation of the previous snippet is:

<ul class="navbar">
  <li>First item</li>
  <li>Second item</li>
</ul>

Handling events

The Ev structure allows to pass functions to handle specific events.

In this example, we set a click event on of the the li:

func handleClick(args []js.Value){
	fmt.Println("I've been clicked!")
}

func main() {
    rootNode := vn.H("ul",  &vn.Props{"class": "navbar"}, vn.Children{
        vn.H("li", &vn.Ev{"click": handleClick}, "First item"),
        vn.H("li", "Second item"),
	})

	vn.patch("#app", rootNode)
}

This module binds the event using the addEventListener API

⚠️ While using event handler, it's necessary to add en empty select{} at the end of the main function

Using keys in list of item

For efficient diffing while you're relying a list of items, you can rely on a key parameter:

vn.H("div", vn.Children{
		vn.H("span", attrsChecked, "Some text"),
	}, &vn.Key{"UNIQUE KEY"})

The key aims to identifiy a Node. It has to be unique and will ensure a quick comparison before handling the computation. The idea is the same (less advanced actually, but here's the idea) as the React key system.

Todos

  • Add more tests 🤦‍♀️ 🤦‍♂️
  • Find a better solution to compare two virtual nodes
  • Ensure consistency and avoid unecessary rerendering that sometimes occur for the same DOMNodes ❓
  • Make a better abstraction concerning the reconciler (it's a really first step)
  • Rely on Go good practices (reference passing, better algorithms and so forth...)
  • Generating the API doc and adding decent comment in code
  • Find a way to abstract the []js.Value passed in every event handler

About

WASM VDOM to create frontend application using Go

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 97.9%
  • Makefile 2.1%
Morty Proxy This is a proxified and sanitized view of the page, visit original site.