Last active
November 6, 2018 15:29
-
-
Save vatson/ab761b3995c78fbd37bb93cf0c12cd0b to your computer and use it in GitHub Desktop.
vue: decorators vs plain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
/*! ***************************************************************************** | |
Copyright (c) Microsoft Corporation. All rights reserved. | |
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | |
this file except in compliance with the License. You may obtain a copy of the | |
License at http://www.apache.org/licenses/LICENSE-2.0 | |
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | |
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | |
MERCHANTABLITY OR NON-INFRINGEMENT. | |
See the Apache Version 2.0 License for specific language governing permissions | |
and limitations under the License. | |
***************************************************************************** */ | |
/* global Reflect, Promise */ | |
var extendStatics = function(d, b) { | |
extendStatics = Object.setPrototypeOf || | |
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | |
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | |
return extendStatics(d, b); | |
}; | |
function __extends(d, b) { | |
extendStatics(d, b); | |
function __() { this.constructor = d; } | |
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | |
} | |
function __decorate(decorators, target, key, desc) { | |
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
return c > 3 && r && Object.defineProperty(target, key, r), r; | |
} | |
function unwrapExports (x) { | |
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x; | |
} | |
function createCommonjsModule(fn, module) { | |
return module = { exports: {} }, fn(module, module.exports), module.exports; | |
} | |
var vueClassComponent_common = createCommonjsModule(function (module, exports) { | |
Object.defineProperty(exports, '__esModule', { value: true }); | |
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | |
var Vue$$1 = _interopDefault(Vue); | |
var reflectionIsSupported = typeof Reflect !== 'undefined' && Reflect.defineMetadata; | |
function copyReflectionMetadata(to, from) { | |
forwardMetadata(to, from); | |
Object.getOwnPropertyNames(from.prototype).forEach(function (key) { | |
forwardMetadata(to.prototype, from.prototype, key); | |
}); | |
Object.getOwnPropertyNames(from).forEach(function (key) { | |
forwardMetadata(to, from, key); | |
}); | |
} | |
function forwardMetadata(to, from, propertyKey) { | |
var metaKeys = propertyKey | |
? Reflect.getOwnMetadataKeys(from, propertyKey) | |
: Reflect.getOwnMetadataKeys(from); | |
metaKeys.forEach(function (metaKey) { | |
var metadata = propertyKey | |
? Reflect.getOwnMetadata(metaKey, from, propertyKey) | |
: Reflect.getOwnMetadata(metaKey, from); | |
if (propertyKey) { | |
Reflect.defineMetadata(metaKey, metadata, to, propertyKey); | |
} | |
else { | |
Reflect.defineMetadata(metaKey, metadata, to); | |
} | |
}); | |
} | |
var fakeArray = { __proto__: [] }; | |
var hasProto = fakeArray instanceof Array; | |
function createDecorator(factory) { | |
return function (target, key, index) { | |
var Ctor = typeof target === 'function' | |
? target | |
: target.constructor; | |
if (!Ctor.__decorators__) { | |
Ctor.__decorators__ = []; | |
} | |
if (typeof index !== 'number') { | |
index = undefined; | |
} | |
Ctor.__decorators__.push(function (options) { return factory(options, key, index); }); | |
}; | |
} | |
function mixins() { | |
var Ctors = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
Ctors[_i] = arguments[_i]; | |
} | |
return Vue$$1.extend({ mixins: Ctors }); | |
} | |
function isPrimitive(value) { | |
var type = typeof value; | |
return value == null || (type !== 'object' && type !== 'function'); | |
} | |
function warn(message) { | |
if (typeof console !== 'undefined') { | |
console.warn('[vue-class-component] ' + message); | |
} | |
} | |
function collectDataFromConstructor(vm, Component) { | |
// override _init to prevent to init as Vue instance | |
var originalInit = Component.prototype._init; | |
Component.prototype._init = function () { | |
var _this = this; | |
// proxy to actual vm | |
var keys = Object.getOwnPropertyNames(vm); | |
// 2.2.0 compat (props are no longer exposed as self properties) | |
if (vm.$options.props) { | |
for (var key in vm.$options.props) { | |
if (!vm.hasOwnProperty(key)) { | |
keys.push(key); | |
} | |
} | |
} | |
keys.forEach(function (key) { | |
if (key.charAt(0) !== '_') { | |
Object.defineProperty(_this, key, { | |
get: function () { return vm[key]; }, | |
set: function (value) { vm[key] = value; }, | |
configurable: true | |
}); | |
} | |
}); | |
}; | |
// should be acquired class property values | |
var data = new Component(); | |
// restore original _init to avoid memory leak (#209) | |
Component.prototype._init = originalInit; | |
// create plain data object | |
var plainData = {}; | |
Object.keys(data).forEach(function (key) { | |
if (data[key] !== undefined) { | |
plainData[key] = data[key]; | |
} | |
}); | |
if (process.env.NODE_ENV !== 'production') { | |
if (!(Component.prototype instanceof Vue$$1) && Object.keys(plainData).length > 0) { | |
warn('Component class must inherit Vue or its descendant class ' + | |
'when class property is used.'); | |
} | |
} | |
return plainData; | |
} | |
var $internalHooks = [ | |
'data', | |
'beforeCreate', | |
'created', | |
'beforeMount', | |
'mounted', | |
'beforeDestroy', | |
'destroyed', | |
'beforeUpdate', | |
'updated', | |
'activated', | |
'deactivated', | |
'render', | |
'errorCaptured' // 2.5 | |
]; | |
function componentFactory(Component, options) { | |
if (options === void 0) { options = {}; } | |
options.name = options.name || Component._componentTag || Component.name; | |
// prototype props. | |
var proto = Component.prototype; | |
Object.getOwnPropertyNames(proto).forEach(function (key) { | |
if (key === 'constructor') { | |
return; | |
} | |
// hooks | |
if ($internalHooks.indexOf(key) > -1) { | |
options[key] = proto[key]; | |
return; | |
} | |
var descriptor = Object.getOwnPropertyDescriptor(proto, key); | |
if (descriptor.value !== void 0) { | |
// methods | |
if (typeof descriptor.value === 'function') { | |
(options.methods || (options.methods = {}))[key] = descriptor.value; | |
} | |
else { | |
// typescript decorated data | |
(options.mixins || (options.mixins = [])).push({ | |
data: function () { | |
var _a; | |
return _a = {}, _a[key] = descriptor.value, _a; | |
} | |
}); | |
} | |
} | |
else if (descriptor.get || descriptor.set) { | |
// computed properties | |
(options.computed || (options.computed = {}))[key] = { | |
get: descriptor.get, | |
set: descriptor.set | |
}; | |
} | |
}); | |
(options.mixins || (options.mixins = [])).push({ | |
data: function () { | |
return collectDataFromConstructor(this, Component); | |
} | |
}); | |
// decorate options | |
var decorators = Component.__decorators__; | |
if (decorators) { | |
decorators.forEach(function (fn) { return fn(options); }); | |
delete Component.__decorators__; | |
} | |
// find super | |
var superProto = Object.getPrototypeOf(Component.prototype); | |
var Super = superProto instanceof Vue$$1 | |
? superProto.constructor | |
: Vue$$1; | |
var Extended = Super.extend(options); | |
forwardStaticMembers(Extended, Component, Super); | |
if (reflectionIsSupported) { | |
copyReflectionMetadata(Extended, Component); | |
} | |
return Extended; | |
} | |
var reservedPropertyNames = [ | |
// Unique id | |
'cid', | |
// Super Vue constructor | |
'super', | |
// Component options that will be used by the component | |
'options', | |
'superOptions', | |
'extendOptions', | |
'sealedOptions', | |
// Private assets | |
'component', | |
'directive', | |
'filter' | |
]; | |
function forwardStaticMembers(Extended, Original, Super) { | |
// We have to use getOwnPropertyNames since Babel registers methods as non-enumerable | |
Object.getOwnPropertyNames(Original).forEach(function (key) { | |
// `prototype` should not be overwritten | |
if (key === 'prototype') { | |
return; | |
} | |
// Some browsers does not allow reconfigure built-in properties | |
var extendedDescriptor = Object.getOwnPropertyDescriptor(Extended, key); | |
if (extendedDescriptor && !extendedDescriptor.configurable) { | |
return; | |
} | |
var descriptor = Object.getOwnPropertyDescriptor(Original, key); | |
// If the user agent does not support `__proto__` or its family (IE <= 10), | |
// the sub class properties may be inherited properties from the super class in TypeScript. | |
// We need to exclude such properties to prevent to overwrite | |
// the component options object which stored on the extended constructor (See #192). | |
// If the value is a referenced value (object or function), | |
// we can check equality of them and exclude it if they have the same reference. | |
// If it is a primitive value, it will be forwarded for safety. | |
if (!hasProto) { | |
// Only `cid` is explicitly exluded from property forwarding | |
// because we cannot detect whether it is a inherited property or not | |
// on the no `__proto__` environment even though the property is reserved. | |
if (key === 'cid') { | |
return; | |
} | |
var superDescriptor = Object.getOwnPropertyDescriptor(Super, key); | |
if (!isPrimitive(descriptor.value) && | |
superDescriptor && | |
superDescriptor.value === descriptor.value) { | |
return; | |
} | |
} | |
// Warn if the users manually declare reserved properties | |
if (process.env.NODE_ENV !== 'production' && | |
reservedPropertyNames.indexOf(key) >= 0) { | |
warn("Static property name '" + key + "' declared on class '" + Original.name + "' " + | |
'conflicts with reserved property name of Vue internal. ' + | |
'It may cause unexpected behavior of the component. Consider renaming the property.'); | |
} | |
Object.defineProperty(Extended, key, descriptor); | |
}); | |
} | |
function Component(options) { | |
if (typeof options === 'function') { | |
return componentFactory(options); | |
} | |
return function (Component) { | |
return componentFactory(Component, options); | |
}; | |
} | |
Component.registerHooks = function registerHooks(keys) { | |
$internalHooks.push.apply($internalHooks, keys); | |
}; | |
exports.default = Component; | |
exports.createDecorator = createDecorator; | |
exports.mixins = mixins; | |
}); | |
var Component = unwrapExports(vueClassComponent_common); | |
var vueClassComponent_common_1 = vueClassComponent_common.createDecorator; | |
var vueClassComponent_common_2 = vueClassComponent_common.mixins; | |
/** vue-property-decorator verson 7.2.0 MIT LICENSE copyright 2018 kaorun343 */ | |
/** | |
* decorator of a prop | |
* @param options the options for the prop | |
* @return PropertyDecorator | void | |
*/ | |
function Prop(options) { | |
if (options === void 0) { options = {}; } | |
return vueClassComponent_common_1(function (componentOptions, k) { | |
(componentOptions.props || (componentOptions.props = {}))[k] = options; | |
}); | |
} | |
var DecoratedComponent = /** @class */ (function (_super) { | |
__extends(DecoratedComponent, _super); | |
function DecoratedComponent() { | |
return _super !== null && _super.apply(this, arguments) || this; | |
} | |
Object.defineProperty(DecoratedComponent.prototype, "greeting", { | |
get: function () { | |
return "Hello, " + this.name; | |
}, | |
enumerable: true, | |
configurable: true | |
}); | |
DecoratedComponent.prototype.cssStyles = function () { | |
return ['smth']; | |
}; | |
__decorate([ | |
Prop(String) | |
], DecoratedComponent.prototype, "name", void 0); | |
DecoratedComponent = __decorate([ | |
Component | |
], DecoratedComponent); | |
return DecoratedComponent; | |
}(Vue)); | |
export { DecoratedComponent }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
import { Component, Prop } from 'vue-property-decorator'; | |
@Component | |
export class DecoratedComponent extends Vue { | |
@Prop(String) | |
public name: string; | |
public get greeting(): string { | |
return `Hello, ${this.name}`; | |
} | |
public cssStyles(): string[] { | |
return ['smth']; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import vue from 'vue'; | |
var PlainComponent = vue.extend({ | |
props: { | |
name: String, | |
}, | |
computed: { | |
greeting: function () { | |
return "Hello, " + this.name; | |
} | |
}, | |
methods: { | |
cssStyles: function () { | |
return ['smth']; | |
} | |
}, | |
}); | |
export { PlainComponent }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import vue from 'vue'; | |
export const PlainComponent = vue.extend({ | |
props: { | |
name: String, | |
}, | |
computed: { | |
greeting(): string { | |
return `Hello, ${this.name}`; | |
} | |
}, | |
methods: { | |
cssStyles(): string[] { | |
return ['smth']; | |
} | |
}, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment