-
Notifications
You must be signed in to change notification settings - Fork 13
/
option.go
131 lines (117 loc) · 3.95 KB
/
option.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package vue
import (
"reflect"
"runtime"
"strings"
)
// Option uses the option pattern for components.
type Option func(*Comp)
// El is the element option for components.
// The root element of a component is query selected from the value, e.g. #app or body.
func El(el string) Option {
return func(comp *Comp) {
comp.el = el
}
}
// Template is the template option for components.
// The template uses the mustache syntax for rendering.
// The template must have a single root element.
func Template(tmpl string) Option {
return func(comp *Comp) {
comp.tmpl = tmpl
}
}
// Data is the data option for components.
// This option accepts either a function or a struct.
// The data function is expected to return a new data value.
// For example: func() *Type { return &Type{...} }
// Without a function the data is shared across components.
// The scope of the data is within the component.
// Data must be a pointer to be mutable by methods.
func Data(data interface{}) Option {
return func(comp *Comp) {
comp.data = data
}
}
// Method is the method option for components.
// The given name and function is registered as a method for the component.
// The function is required to accept context and allows optional arguments.
// For example: func(vctx vue.Context) or func(vctx vue.Context, a1 Arg1, ..., ak ArgK)
func Method(name string, function interface{}) Option {
return func(comp *Comp) {
comp.methods[name] = reflect.ValueOf(function)
}
}
// Methods is the methods option for components.
// The given functions are registered as methods for the component.
// The functions are required to accept context and allows optional arguments.
// For example: func(vctx vue.Context) or func(vctx vue.Context, a1 Arg1, ..., ak ArgK)
func Methods(functions ...interface{}) Option {
return func(comp *Comp) {
for _, function := range functions {
fn := reflect.ValueOf(function)
name := funcName(fn)
comp.methods[name] = fn
}
}
}
// Computed is the computed option for components.
// The given name and function is registered as a computed property for the component.
// The function is required to accept context and return a value.
// For example: func(vctx vue.Context) Type
func Computed(name string, function interface{}) Option {
return func(comp *Comp) {
fn := reflect.ValueOf(function)
comp.computed[name] = fn
}
}
// Computeds is the computeds option for components.
// The given functions are registered as computed properties for the component.
// The functions are required to accept context and return a value.
// For example: func(vctx vue.Context) Type
func Computeds(functions ...interface{}) Option {
return func(comp *Comp) {
for _, function := range functions {
fn := reflect.ValueOf(function)
name := funcName(fn)
comp.computed[name] = fn
}
}
}
// Watch is the watch option for components.
// The given function is registered as a watcher for the data field.
// All data fields are watchable, e.g. data, props and computed.
// The function is required to accept context and both the new and old values.
// For example: func(vctx vue.Context, newVal, oldVal Type)
func Watch(field string, function interface{}) Option {
return func(comp *Comp) {
fn := reflect.ValueOf(function)
comp.watchers[field] = fn
}
}
// Sub is the subcomponent option for components.
func Sub(element string, sub *Comp) Option {
return func(comp *Comp) {
sub.isSub = true
comp.subs[element] = sub
}
}
// Props is the props option for subcomponents.
func Props(props ...string) Option {
return func(sub *Comp) {
for _, prop := range props {
sub.props[prop] = struct{}{}
}
}
}
// funcName returns the name of the given function.
func funcName(function reflect.Value) string {
name := runtime.FuncForPC(function.Pointer()).Name()
return stripMetadata(name)
}
// stripMetadata returns the function name without metadata.
func stripMetadata(name string) string {
parts := strings.Split(name, ".")
name = parts[len(parts)-1]
return strings.TrimSuffix(name, "-fm")
}