hvue

package module
v0.0.0-...-02dc3ed Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2018 License: MIT Imports: 2 Imported by: 1

README

Intro

hvue is a GopherJS and wasm wrapper for the Vue Javascript framework.

This (the "master" branch) is the go/wasm + GopherJS version. It uses gopherwasm to provide a compatability layer between go/wasm and GopherJS. go/wasm is patterned on GopherJS, but doesn't have all of its capabilities and language-specific "magic". In particular, go/wasm doesn't have GopherJS's "dual struct/object" magic, which allows you to embed a *js.Object in a struct, define struct fields with js:"jsName" tags, and have the compiler automatically change references to those fields into references to fields in the inner *js.Object. So to access a JavaScript object in go/wasm, you have to use a "naked" js.Value and either use thing.Get("jsField") (and related functions) everywhere (ew) or write access functions (less ew). You can also write GopherJS in the same style, and gopherwasm creates a compatability layer so the go/wasm style compiles under GopherJS.

The GopherJS-only version is tagged as v1, and also as gopherjs.

The wasm branch still exists, because I shared it pretty widely, and I want those links to keep working for a while.

So if you want to use the go/wasm code, and/or also use this exact code in GopherJS, use this branch. If you want the GopherJS-only code, use the v1 or gopherjs branch. Click on over to the README in that branch for installation instructions. They may need modification, since they still date to when hvue's "master" branch was GopherJS-only.

Install

Install Go 1.11

See https://golang.org/dl/.

Install hvue

(Side note: If you skipped it, please make sure you've read the Intro above about the difference between this (the go/wasm + GopherJS code), and previous GopherJS-only versions.)

cd path/to/github.com # in your $GOPATH
mkdir huckridgesw
cd huckridgesw
git clone git@github.com:HuckRidgeSW/hvue.git

Examples & Demos

Overview

Generally speaking, the examples follow the examples in the Vue guide. Some don't, because the Guide has changed since I wrote the examples. But most of them do.

01-introduction has examples from the Vue Introduction page.

02-lifecycle demos Vue lifecycle hooks but does not correspond to any specific example on that page.

03-computed-basic and 04-computed-with-setter have examples from Computed Properties and Watchers.

And so on. Links are in the code.

Running the examples

GopherJS
cd path/to/github.com/huckridgesw/hvue
echo "var hvue_wasm = false;" > examples/maybe_wasm.js
gopherjs serve github.com/huckridgesw/hvue # listens on 8080

and then

WASM
cd path/to/github.com/huckridgesw/hvue
echo "var hvue_wasm = true;" > examples/maybe_wasm.js
go run examples/server/main.go # Listens on 8081
cd examples/??-???? # some examples directory
GOARCH=wasm GOOS=js go build -o ${PWD##*/}.wasm main.go # compile wasm

and then

Remember to recompile after any changes. There's no facility yet to auto-build (a-la gopherjs build -w or gopherjs serve).

Switching from GopherJS to WASM and back
  • Do the appropriate "echo "var hvue_wasm = ?;" > examples/maybe_wasm.js. (See above.)
  • Be sure to do "shift-cmd-R" (Chrome, macOS; other browsers / OSes will vary) to reload without using the cache, to get the new maybe_wasm.js and/or new wasm. (Actually I'm not sure you need that to get new wasm, since it's loaded via an explicit fetch() call, but it's probably not a bad idea.) Alternatively, in Chrome you can open the developer console, go to the network tab, and check "disable cache". (AIUI only works while said console window is open.)

GoDoc

http://godoc.org/github.com/HuckRidgeSW/hvue

Documentation

Index

Constants

View Source
const (
	PString   pOptionType = iota
	PNumber               = iota
	PBoolean              = iota
	PFunction             = iota
	PObject               = iota
	PArray                = iota
)

Variables

This section is empty.

Functions

func Log

func Log(args ...interface{})

func Map2Obj

func Map2Obj(m M) js.Value

func NewArray

func NewArray() js.Value

NewArray is a utility function for creating a new JS array.

func NewCallback

func NewCallback(f func(this js.Value, args []js.Value) interface{}) js.Value

func NewComponent

func NewComponent(name string, opts ...ComponentOption)

NewComponent defines a new Vue component. It wraps js{Vue.component}: https://vuejs.org/v2/api/#Vue-component.

func NewObject

func NewObject() js.Value

NewObject is a utility function for creating a new JavaScript Object of type js.Value.

func Push

func Push(o js.Value, any interface{}) (newLength int)

Push appends any to the end of o, in place.

func Set

func Set(o, key, value interface{}) interface{}

Set is a wrapper for js{Vue.set}

Types

type ComponentOption

type ComponentOption func(*Config)

func Activated

func Activated(f func(vm *VM)) ComponentOption

Activated lets you define a hook for the activated lifecycle action. Only runs in Vue-defined components (e.g. not regular DIVs) inside a <keep-alive>. "Called when a kept-alive component is activated." https://vuejs.org/v2/api/#activated and https://vuejs.org/v2/api/#keep-alive

func BeforeCreate

func BeforeCreate(f func(vm *VM)) ComponentOption

BeforeCreate lets you define a hook for the beforeCreate lifecycle action. "Called synchronously after the instance has just been initialized, before data observation and event/watcher setup." https://vuejs.org/v2/api/#beforeCreate

func BeforeDestroy

func BeforeDestroy(f func(vm *VM)) ComponentOption

BeforeDestroy lets you define a hook for the beforeDestroy lifecycle action. "Called right before a Vue instance is destroyed. At this stage the instance is still fully functional." https://vuejs.org/v2/api/#beforeDestroy

func BeforeMount

func BeforeMount(f func(vm *VM)) ComponentOption

BeforeMount lets you define a hook for the beforeMount lifecycle action. "Called right before the mounting begins: the render function is about to be called for the first time." https://vuejs.org/v2/api/#beforeMount

func BeforeUpdate

func BeforeUpdate(f func(vm *VM)) ComponentOption

BeforeUpdate lets you define a hook for the beforeUpdate lifecycle action. "Called when the data changes, before the virtual DOM is re-rendered and patched.

You can perform further state changes in this hook and they will not trigger additional re-renders." https://vuejs.org/v2/api/#beforeUpdate

func Component

func Component(name string, opts ...ComponentOption) ComponentOption

Component is used in NewVM to define a local component, within the scope of another instance/component. https://vuejs.org/v2/guide/components.html#Local-Registration

func Computed

func Computed(name string, f func(vm *VM) interface{}) ComponentOption

Computed defines name as a computed property. Note that name *must not* be set in data for this to work. It's probably best if it's not even a slot in the struct. Only access it via vm.Get. You could also create an accessor; see the 04-computed-with-setter example.

Computed functions require synchronous functions that can return values to Vue. Go/wasm cannot support either of those things just yet. So currently this function just panics.

Use a watcher instead.

func ComputedWithGetSet

func ComputedWithGetSet(name string, get func(vm *VM) interface{}, set func(vm *VM, newValue js.Value)) ComponentOption

ComputedWithGetSet defines name as a computed property with explicit get & set. Note that name *must not* be set in data for this to work. It's probably best if it's not even a slot in the struct. Only access it via vm.Get/Set. You could create an accessor; see the 04-computed-with-setter example.

Computed functions require synchronous functions that can return values to Vue. Go/wasm cannot support either of those things just yet. So currently this function just panics.

Use a watcher instead.

func Created

func Created(f func(vm *VM)) ComponentOption

Created lets you define a hook for the created lifecycle action. "Called synchronously after the instance is created. At this stage, the instance has finished processing the options which means the following have been set up: data observation, computed properties, methods, watch/event callbacks. However, the mounting phase has not been started, and the $el property will not be available yet." https://vuejs.org/v2/api/#created

func Data

func Data(name string, value interface{}) ComponentOption

Data sets a single data field. Data can be called multiple times for the same vm.

Note that you can't use MethodsOf with this function.

func DataFunc

func DataFunc(f DataFuncT, fieldNames ...string) ComponentOption

DataFunc defines a function that returns a new data object. You have to use DataFunc with Components, not Data or DataS.

Note that this function is called when the VM or component is created (https://vuejs.org/v2/api/#created), not when you call "NewVM". This means that you can't, for example, get clever and try to use the same object here as with MethodsOf. MethodsOf requires an object when you call NewVM to register the VM, long before the VM is actually created or bound; this is called every time a new VM or component is created.

func DataS

func DataS(goValue interface{}, jsValue js.Value) ComponentOption

DataS sets the object `goValue` as the entire contents of the vm's data field. If the object has a VM field, NewVM sets it to the new VM object.

func Deactivated

func Deactivated(f func(vm *VM)) ComponentOption

Deactivated lets you define a hook for the deactivated lifecycle action. Only runs in Vue-defined components (e.g. not regular DIVs) inside a <keep-alive>. "Called when a kept-alive component is deactivated." https://vuejs.org/v2/api/#deactivated and https://vuejs.org/v2/api/#keep-alive

func Destroyed

func Destroyed(f func(vm *VM)) ComponentOption

Destroyed lets you define a hook for the destroyed lifecycle action. "Called after a Vue instance has been destroyed. When this hook is called, all directives of the Vue instance have been unbound, all event listeners have been removed, and all child Vue instances have also been destroyed." https://vuejs.org/v2/api/#destroyed

func El

func El(selector string) ComponentOption

El sets the vm's el slot.

func Method

func Method(name string, f interface{}) ComponentOption

Method adds a single function as a "method" on a vm. It does not change the method set of the data object, if any.

func MethodsOf

func MethodsOf(t interface{}) ComponentOption

MethodsOf sets up vm.methods with the exported methods of the type that t is an instance of. Call it like MethodsOf(&SomeType{}). SomeType must be a pure Javascript object, with no Go fields. That is, all slots just have `js:"..."` tags.

If a method wants a pointer to its vm, use a *VM as the first argument.

You can't use MethodsOf with Data(), only with DataS or DataFunc().

func Mounted

func Mounted(f func(vm *VM)) ComponentOption

Mounted lets you define a hook for the mounted lifecycle action. "Called after the instance has just been mounted where el is replaced by the newly created vm.$el. If the root instance is mounted to an in-document element, vm.$el will also be in-document when mounted is called." https://vuejs.org/v2/api/#mounted

func PropObj

func PropObj(name string, opts ...PropOption) ComponentOption

PropObj defines a complex prop slot called `name`, configured with Types, Default, DefaultFunc, and Validator.

func Props

func Props(props ...string) ComponentOption

Props defines one or more simple prop slots. For complex prop slots, use PropObj(). https://vuejs.org/v2/api/#props

func Template

func Template(template string) ComponentOption

Template defines a template for a component. It sets the js{template} slot of a js{Vue.component}'s configuration object.

func Updated

func Updated(f func(vm *VM)) ComponentOption

Updated lets you define a hook for the updated lifecycle action. "Called after a data change causes the virtual DOM to be re-rendered and patched.

The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here. However, in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead." https://vuejs.org/v2/api/#updated

func Watch

func Watch(name string, f func(*VM)) ComponentOption

type Config

type Config struct {
	js.Value

	DataType js.Type
	// contains filtered or unexported fields
}

Config is the config object for NewVM.

func (*Config) Components

func (c *Config) Components() js.Value

func (*Config) Computed

func (c *Config) Computed() js.Value

func (*Config) Data

func (c *Config) Data() js.Value

Data and DataFunc both return the same underlying slot.

func (*Config) DataFunc

func (c *Config) DataFunc() js.Value

func (*Config) El

func (c *Config) El() string

func (*Config) Filters

func (c *Config) Filters() js.Value

func (*Config) Methods

func (c *Config) Methods() js.Value

func (*Config) Option

func (c *Config) Option(opts ...ComponentOption)

Option sets the options specified.

func (*Config) Props

func (c *Config) Props() js.Value

func (*Config) SetComponents

func (c *Config) SetComponents(new js.Value)

func (*Config) SetComputed

func (c *Config) SetComputed(new js.Value)

func (*Config) SetData

func (c *Config) SetData(new js.Value)

SetData and SetDataFunc both set the same underlying slot.

func (*Config) SetDataFunc

func (c *Config) SetDataFunc(newF DataFuncT, fieldNames ...string)

func (*Config) SetEl

func (c *Config) SetEl(new string)

func (*Config) SetFilters

func (c *Config) SetFilters(new js.Value)

func (*Config) SetMethods

func (c *Config) SetMethods(new js.Value)

func (*Config) SetProps

func (c *Config) SetProps(new js.Value)

func (*Config) SetSetters

func (c *Config) SetSetters(new js.Value)

func (*Config) SetTemplate

func (c *Config) SetTemplate(new string)

func (*Config) SetWatchers

func (c *Config) SetWatchers(new js.Value)

func (*Config) Setters

func (c *Config) Setters() js.Value

func (*Config) Template

func (c *Config) Template() string

func (*Config) Watchers

func (c *Config) Watchers() js.Value

type DataFuncT

type DataFuncT func(vm *VM, dataObj js.Value) interface{}

The type of function passed to SetDataFunc, to initialize the fields for a new data object in a Vue component.

type Directive

type Directive struct {
	js.Value
}

Directive wraps a js{Vue.directive} object. https://vuejs.org/v2/api/#Vue-directive.

func NewDirective

func NewDirective(name string, opts ...DirectiveOption) *Directive

NewDirective creates a new directive. It wraps js{Vue.directive}. https://vuejs.org/v2/api/#Vue-directive

type DirectiveBinding

type DirectiveBinding struct {
	// This js.Value slot has its own slot called "value", so its accessor
	// (below) is called Value(), so the slot name can't also be Value, so call
	// it Val.  Which could actually be surprising if you use
	// DirectiveBinding.Value, because it'll *compile*, but it'll be a
	// function value, not a string, so it'll likely panic.
	Val js.Value
}

DirectiveBinding wraps the js{binding} slot of the directive hook argument. https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments

func (*DirectiveBinding) Arg

func (db *DirectiveBinding) Arg() string

func (*DirectiveBinding) Expression

func (db *DirectiveBinding) Expression() string

func (*DirectiveBinding) Modifiers

func (db *DirectiveBinding) Modifiers() js.Value

func (*DirectiveBinding) Name

func (db *DirectiveBinding) Name() string

func (*DirectiveBinding) OldValue

func (db *DirectiveBinding) OldValue() js.Value

func (*DirectiveBinding) Value

func (db *DirectiveBinding) Value() js.Value

type DirectiveConfig

type DirectiveConfig struct {
	js.Value
}

DirectiveConfig is the config object for configuring a directive.

func (*DirectiveConfig) Option

func (c *DirectiveConfig) Option(opts ...DirectiveOption)

func (*DirectiveConfig) SetShort

func (dc *DirectiveConfig) SetShort(new js.Value)

func (*DirectiveConfig) Short

func (dc *DirectiveConfig) Short() js.Value

type DirectiveOption

type DirectiveOption func(*DirectiveConfig)

func Bind

func Bind(f func(el js.Value, binding *DirectiveBinding, vnode js.Value)) DirectiveOption

Bind specifies the js{bind} directive hook function. Called only once, when the directive is first bound to the element. This is where you can do one-time setup work. https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions

func ComponentUpdated

func ComponentUpdated(f func(el js.Value, binding *DirectiveBinding, vnode, oldVode js.Value)) DirectiveOption

ComponentUpdated specifies the js{componentUpdated} directive hook function. Called after the containing component and its children have updated. https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions

func Inserted

func Inserted(f func(el js.Value, binding *DirectiveBinding, vnode js.Value)) DirectiveOption

Inserted specifies the js{inserted} directive hook function. Called when the bound element has been inserted into its parent node (this only guarantees parent node presence, not necessarily in-document). https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions

func Short

func Short(f func(el js.Value, binding *DirectiveBinding, vnode, oldVnode js.Value)) DirectiveOption

Short allows you to use the "function shorthand" style of directive definition, when you want the same behavior on bind and update, but don't care about the other hooks. oldVnode is only used for the update hook; for the bind hook, it's nil. https://vuejs.org/v2/guide/custom-directive.html#Function-Shorthand

func Unbind

func Unbind(f func(el js.Value, binding *DirectiveBinding, vnode js.Value)) DirectiveOption

Unbind specifies the js{unbind} directive hook function. Called only once, when the directive is unbound from the element. https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions

func Update

func Update(f func(el js.Value, binding *DirectiveBinding, vnode, oldVnode js.Value)) DirectiveOption

Update specifies the js{update} directive hook function. Called after the containing component has updated, but possibly before its children have updated. The directive’s value may or may not have changed, but you can skip unnecessary updates by comparing the binding’s current and old values (see the Vue Guide on hook arguments). https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions

type Event

type Event struct {
	js.Value
}

Event wraps the event object sent to v-on event handlers.

I've only implemented enough of the Event type (https://developer.mozilla.org/en-US/docs/Web/API/Event) to implement example 07.

func (*Event) Target

func (e *Event) Target() *HTMLElement

type HTMLElement

type HTMLElement struct {
	js.Value
}

func (*HTMLElement) Select

func (et *HTMLElement) Select()

type M

type M map[string]interface{}

Modeled on GopherJS's js.M, also a map[string]interface{}

type PropConfig

type PropConfig struct {
	js.Value
}

PropConfig is the config object for Props

func (*PropConfig) Option

func (p *PropConfig) Option(opts ...PropOption)

func (*PropConfig) SetDefault

func (pc *PropConfig) SetDefault(d interface{})

func (*PropConfig) SetRequired

func (pc *PropConfig) SetRequired(r bool)

func (*PropConfig) SetType

func (pc *PropConfig) SetType(t js.Value)

type PropOption

type PropOption func(*PropConfig)
var Required PropOption = func(p *PropConfig) {
	p.SetRequired(true)
}

Required specifies that the prop is required. https://vuejs.org/v2/guide/components.html#Props.

func Default

func Default(def interface{}) PropOption

Default gives the default for a prop. https://vuejs.org/v2/guide/components.html#Props

func DefaultFunc

func DefaultFunc(def js.Value) PropOption

DefaultFunc sets a function that returns the default for a prop. https://vuejs.org/v2/guide/components.html#Props

FIXME: Right now, can only pass an object (not a function). The JS helper function copies it to a new object. Later, need to be able to pass a function, which returns a new value.

func Types

func Types(types ...pOptionType) PropOption

Types configures the allowed types for a prop. https://vuejs.org/v2/guide/components.html#Props.

func Validator

func Validator(f func(vm *VM, value js.Value) interface{}) PropOption

Validator functions generate warnings in the JS console if using the vue.js development build. They don't panic or otherwise crash your code, they just give warnings if the validation fails.

FIXME: Currently does nothing, because in 1.11 Go functions called from JS can't return values.

type VM

type VM struct {
	js.Value
}

VM wraps a js Vue object.

func NewVM

func NewVM(opts ...ComponentOption) *VM

NewVM returns a new vm, analogous to Javascript `new Vue(...)`. See https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis and https://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html for discussions of how the options work, and also see the examples tree.

If you use a data object (via DataS) and it has a VM field, it's set to this new VM. TODO: Verify that the VM field is of type *hvue.VM.

func (*VM) Data

func (vm *VM) Data() js.Value

func (*VM) El

func (vm *VM) El() js.Value

func (*VM) Emit

func (vm *VM) Emit(event string, args ...interface{})

Emit emits an event. It wraps js{vm.$emit}: https://vuejs.org/v2/api/#vm-emit.

func (*VM) GetData

func (vm *VM) GetData() interface{}

GetData returns the Go data object associated with a *VM. You need to type assert its return value to data type you passed to DataS(), or returned from the function given to DataFunc().

func (*VM) IsServer

func (vm *VM) IsServer() bool

func (*VM) Options

func (vm *VM) Options() js.Value

func (*VM) Parent

func (vm *VM) Parent() js.Value

func (*VM) Props

func (vm *VM) Props() js.Value

func (*VM) Refs

func (vm *VM) Refs(name string) js.Value

Refs returns the ref for name. vm.Refs("foo") compiles to js{vm.$refs.foo}. It wraps vm.$refs: https://vuejs.org/v2/api/#vm-refs.

func (*VM) Root

func (vm *VM) Root() js.Value

func (*VM) ScopedSlots

func (vm *VM) ScopedSlots() js.Value

func (*VM) Set

func (vm *VM) Set(key string, value interface{})

Set wraps vm.Value.Set(), but checks to make sure the given field is a valid slot in the VM's data object (including computed setters), and panics otherwise. (If you don't want this check, then use vm.Value.Set() directly.)

func (*VM) SetSetters

func (vm *VM) SetSetters(new js.Value)

func (*VM) Setters

func (vm *VM) Setters() js.Value

Note existence of fields with setter methods, which won't show up in $data.

func (*VM) Slots

func (vm *VM) Slots() js.Value

func (vm *VM) Children() []js.Value { return vm.Get("$children") } // not sure about this one

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL