UNPKG

4.23 kBJavaScriptView Raw
1function isFunction(value) {
2 return typeof value === 'function';
3}
4function getSuperOptions(Ctor) {
5 const superProto = Object.getPrototypeOf(Ctor.prototype);
6 if (!superProto) {
7 return undefined;
8 }
9 const Super = superProto.constructor;
10 return Super.__vccOpts;
11}
12export class Vue {
13 constructor(props) {
14 this.$props = props;
15 Object.keys(props).forEach(key => {
16 Object.defineProperty(this, key, {
17 enumerable: false,
18 configurable: true,
19 writable: true,
20 value: props[key]
21 });
22 });
23 }
24 /** @internal */
25 static get __vccOpts() {
26 // Early return if `this` is base class as it does not have any options
27 if (this === Vue) {
28 return {};
29 }
30 const cache = this.hasOwnProperty('__vccCache') && this.__vccCache;
31 if (cache) {
32 return cache;
33 }
34 const Ctor = this;
35 // If the options are provided via decorator use it as a base
36 const options = this.__vccCache = this.hasOwnProperty('__vccBase')
37 ? { ...this.__vccBase }
38 : {};
39 // Handle super class options
40 options.extends = getSuperOptions(Ctor);
41 // Handle mixins
42 const mixins = this.hasOwnProperty('__vccMixins') && this.__vccMixins;
43 if (mixins) {
44 options.mixins = options.mixins ? options.mixins.concat(mixins) : mixins;
45 }
46 // Class name -> component name
47 options.name = options.name || Ctor.name;
48 options.methods = { ...options.methods };
49 options.computed = { ...options.computed };
50 const proto = Ctor.prototype;
51 Object.getOwnPropertyNames(proto).forEach(key => {
52 if (key === 'constructor') {
53 return;
54 }
55 // hooks
56 if (Ctor.__vccHooks.indexOf(key) > -1) {
57 options[key] = proto[key];
58 return;
59 }
60 const descriptor = Object.getOwnPropertyDescriptor(proto, key);
61 // methods
62 if (typeof descriptor.value === 'function') {
63 options.methods[key] = descriptor.value;
64 return;
65 }
66 // computed properties
67 if (descriptor.get || descriptor.set) {
68 options.computed[key] = {
69 get: descriptor.get,
70 set: descriptor.set
71 };
72 return;
73 }
74 });
75 // Class properties -> reactive data
76 const hookDataOption = options.data;
77 options.data = function () {
78 const hookData = isFunction(hookDataOption)
79 ? hookDataOption.call(this, this)
80 : hookDataOption;
81 // should be acquired class property values
82 const data = new Ctor(this.$props);
83 // create plain data object
84 const plainData = {};
85 Object.keys(data).forEach(key => {
86 if (data[key] !== undefined && key !== '$props') {
87 plainData[key] = data[key];
88 }
89 });
90 return {
91 ...hookData,
92 ...plainData
93 };
94 };
95 const decorators = this.hasOwnProperty('__vccDecorators') && this.__vccDecorators;
96 if (decorators) {
97 decorators.forEach(fn => fn(options));
98 }
99 // from Vue Loader
100 if (Ctor.render) {
101 options.render = Ctor.render;
102 }
103 if (Ctor.__file) {
104 options.__file = Ctor.__file;
105 }
106 if (Ctor.__cssModules) {
107 options.__cssModules = Ctor.__cssModules;
108 }
109 if (Ctor.__scopeId) {
110 options.__scopeId = Ctor.__scopeId;
111 }
112 return options;
113 }
114 static registerHooks(keys) {
115 this.__vccHooks.push(...keys);
116 }
117}
118/** @internal */
119Vue.__vccHooks = [
120 'data',
121 'beforeCreate',
122 'created',
123 'beforeMount',
124 'mounted',
125 'beforeUnmount',
126 'unmounted',
127 'beforeUpdate',
128 'updated',
129 'activated',
130 'deactivated',
131 'render',
132 'errorCaptured',
133 'serverPrefetch'
134];