forked from vuejs/vue-class-component
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomponent.ts
76 lines (70 loc) · 2.03 KB
/
component.ts
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
import Vue, { ComponentOptions } from 'vue'
import { VueClass, DecoratedClass } from './declarations'
import { collectDataFromConstructor } from './data'
export const $internalHooks = [
'data',
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeDestroy',
'destroyed',
'beforeUpdate',
'updated',
'activated',
'deactivated',
'render',
'errorCaptured' // 2.5
]
export function componentFactory (
Component: VueClass<Vue>,
options: ComponentOptions<any, any, any, any> = {}
): VueClass<Vue> {
options.name = options.name || (Component as any)._componentTag || (Component as any).name
// prototype props.
const proto = Component.prototype
Object.getOwnPropertyNames(proto).forEach(function (key) {
if (key === 'constructor') {
return
}
// hooks
if ($internalHooks.indexOf(key) > -1) {
options[key] = proto[key]
return
}
const descriptor = Object.getOwnPropertyDescriptor(proto, key)!
if (typeof descriptor.value === 'function') {
// methods
(options.methods || (options.methods = {}))[key] = descriptor.value
} else if (descriptor.get || descriptor.set) {
// computed properties
(options.computed || (options.computed = {}))[key] = {
get: descriptor.get,
set: descriptor.set
}
}
})
// add data hook to collect class properties as Vue instance's data
;(options.mixins || (options.mixins = [])).push({
data (this: Vue) {
return collectDataFromConstructor(this, Component)
}
})
// decorate options
const decorators = (Component as DecoratedClass).__decorators__
if (decorators) {
decorators.forEach(fn => fn(options))
}
// find super
const superProto = Object.getPrototypeOf(Component.prototype)
const Super = superProto instanceof Vue
? superProto.constructor as VueClass<Vue>
: Vue
const Extended = Super.extend(options);
for(let staticKey in Component) {
if(Component.hasOwnProperty(staticKey)) {
Extended[staticKey] = Component[staticKey];
}
}
return Extended;
}