This commit is contained in:
2022-07-21 03:28:35 +00:00
parent d7c883d6df
commit 51b34b0e1d
30103 changed files with 4152204 additions and 23 deletions
+4
View File
@@ -0,0 +1,4 @@
import Vue, { ComponentOptions } from 'vue';
import { VueClass } from './declarations';
export declare const $internalHooks: string[];
export declare function componentFactory(Component: VueClass<Vue>, options?: ComponentOptions<Vue>): VueClass<Vue>;
+144
View File
@@ -0,0 +1,144 @@
import Vue from 'vue';
import { copyReflectionMetadata, reflectionIsSupported } from './reflect';
import { collectDataFromConstructor } from './data';
import { hasProto, isPrimitive, warn } from './util';
export const $internalHooks = [
'data',
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeDestroy',
'destroyed',
'beforeUpdate',
'updated',
'activated',
'deactivated',
'render',
'errorCaptured',
'serverPrefetch' // 2.6
];
export function componentFactory(Component, options = {}) {
options.name = options.name || Component._componentTag || Component.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 (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() {
return { [key]: descriptor.value };
}
});
}
}
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() {
return collectDataFromConstructor(this, Component);
}
});
// decorate options
const decorators = Component.__decorators__;
if (decorators) {
decorators.forEach(fn => fn(options));
delete Component.__decorators__;
}
// find super
const superProto = Object.getPrototypeOf(Component.prototype);
const Super = superProto instanceof Vue
? superProto.constructor
: Vue;
const Extended = Super.extend(options);
forwardStaticMembers(Extended, Component, Super);
if (reflectionIsSupported()) {
copyReflectionMetadata(Extended, Component);
}
return Extended;
}
const 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'
];
const shouldIgnore = {
prototype: true,
arguments: true,
callee: true,
caller: true
};
function forwardStaticMembers(Extended, Original, Super) {
// We have to use getOwnPropertyNames since Babel registers methods as non-enumerable
Object.getOwnPropertyNames(Original).forEach(key => {
// Skip the properties that should not be overwritten
if (shouldIgnore[key]) {
return;
}
// Some browsers does not allow reconfigure built-in properties
const extendedDescriptor = Object.getOwnPropertyDescriptor(Extended, key);
if (extendedDescriptor && !extendedDescriptor.configurable) {
return;
}
const 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;
}
const 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);
});
}
+3
View File
@@ -0,0 +1,3 @@
import Vue from 'vue';
import { VueClass } from './declarations';
export declare function collectDataFromConstructor(vm: Vue, Component: VueClass<Vue>): {};
+45
View File
@@ -0,0 +1,45 @@
import Vue from 'vue';
import { warn } from './util';
export function collectDataFromConstructor(vm, Component) {
// override _init to prevent to init as Vue instance
const originalInit = Component.prototype._init;
Component.prototype._init = function () {
// proxy to actual vm
const keys = Object.getOwnPropertyNames(vm);
// 2.2.0 compat (props are no longer exposed as self properties)
if (vm.$options.props) {
for (const key in vm.$options.props) {
if (!vm.hasOwnProperty(key)) {
keys.push(key);
}
}
}
keys.forEach(key => {
if (key.charAt(0) !== '_') {
Object.defineProperty(this, key, {
get: () => vm[key],
set: value => { vm[key] = value; },
configurable: true
});
}
});
};
// should be acquired class property values
const data = new Component();
// restore original _init to avoid memory leak (#209)
Component.prototype._init = originalInit;
// create plain data object
const plainData = {};
Object.keys(data).forEach(key => {
if (data[key] !== undefined) {
plainData[key] = data[key];
}
});
if (process.env.NODE_ENV !== 'production') {
if (!(Component.prototype instanceof Vue) && Object.keys(plainData).length > 0) {
warn('Component class must inherit Vue or its descendant class ' +
'when class property is used.');
}
}
return plainData;
}
+7
View File
@@ -0,0 +1,7 @@
import Vue, { ComponentOptions } from 'vue';
export declare type VueClass<V> = {
new (...args: any[]): V & Vue;
} & typeof Vue;
export declare type DecoratedClass = VueClass<Vue> & {
__decorators__?: ((options: ComponentOptions<Vue>) => void)[];
};
View File
+12
View File
@@ -0,0 +1,12 @@
import Vue, { ComponentOptions } from 'vue';
import { VueClass } from './declarations';
export { createDecorator, VueDecorator, mixins } from './util';
declare function Component<V extends Vue>(options: ComponentOptions<V> & ThisType<V>): <VC extends VueClass<V>>(target: VC) => VC;
declare namespace Component {
var registerHooks: (keys: string[]) => void;
}
declare function Component<VC extends VueClass<Vue>>(target: VC): VC;
declare namespace Component {
var registerHooks: (keys: string[]) => void;
}
export default Component;
+14
View File
@@ -0,0 +1,14 @@
import { componentFactory, $internalHooks } from './component';
export { createDecorator, mixins } from './util';
function Component(options) {
if (typeof options === 'function') {
return componentFactory(options);
}
return function (Component) {
return componentFactory(Component, options);
};
}
Component.registerHooks = function registerHooks(keys) {
$internalHooks.push(...keys);
};
export default Component;
+4
View File
@@ -0,0 +1,4 @@
import Vue, { VueConstructor } from 'vue';
import { VueClass } from './declarations';
export declare function reflectionIsSupported(): false | typeof Reflect.getOwnMetadataKeys;
export declare function copyReflectionMetadata(to: VueConstructor, from: VueClass<Vue>): void;
+31
View File
@@ -0,0 +1,31 @@
// The rational behind the verbose Reflect-feature check below is the fact that there are polyfills
// which add an implementation for Reflect.defineMetadata but not for Reflect.getOwnMetadataKeys.
// Without this check consumers will encounter hard to track down runtime errors.
export function reflectionIsSupported() {
return typeof Reflect !== 'undefined' && Reflect.defineMetadata && Reflect.getOwnMetadataKeys;
}
export function copyReflectionMetadata(to, from) {
forwardMetadata(to, from);
Object.getOwnPropertyNames(from.prototype).forEach(key => {
forwardMetadata(to.prototype, from.prototype, key);
});
Object.getOwnPropertyNames(from).forEach(key => {
forwardMetadata(to, from, key);
});
}
function forwardMetadata(to, from, propertyKey) {
const metaKeys = propertyKey
? Reflect.getOwnMetadataKeys(from, propertyKey)
: Reflect.getOwnMetadataKeys(from);
metaKeys.forEach(metaKey => {
const 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);
}
});
}
+18
View File
@@ -0,0 +1,18 @@
import Vue, { ComponentOptions } from 'vue';
import { VueClass } from './declarations';
export declare const noop: () => void;
export declare const hasProto: boolean;
export interface VueDecorator {
(Ctor: typeof Vue): void;
(target: Vue, key: string): void;
(target: Vue, key: string, index: number): void;
}
export declare function createDecorator(factory: (options: ComponentOptions<Vue>, key: string, index: number) => void): VueDecorator;
export declare function mixins<A>(CtorA: VueClass<A>): VueClass<A>;
export declare function mixins<A, B>(CtorA: VueClass<A>, CtorB: VueClass<B>): VueClass<A & B>;
export declare function mixins<A, B, C>(CtorA: VueClass<A>, CtorB: VueClass<B>, CtorC: VueClass<C>): VueClass<A & B & C>;
export declare function mixins<A, B, C, D>(CtorA: VueClass<A>, CtorB: VueClass<B>, CtorC: VueClass<C>, CtorD: VueClass<D>): VueClass<A & B & C & D>;
export declare function mixins<A, B, C, D, E>(CtorA: VueClass<A>, CtorB: VueClass<B>, CtorC: VueClass<C>, CtorD: VueClass<D>, CtorE: VueClass<E>): VueClass<A & B & C & D & E>;
export declare function mixins<T>(...Ctors: VueClass<Vue>[]): VueClass<T>;
export declare function isPrimitive(value: any): boolean;
export declare function warn(message: string): void;
+30
View File
@@ -0,0 +1,30 @@
import Vue from 'vue';
export const noop = () => { };
const fakeArray = { __proto__: [] };
export const hasProto = fakeArray instanceof Array;
export function createDecorator(factory) {
return (target, key, index) => {
const Ctor = typeof target === 'function'
? target
: target.constructor;
if (!Ctor.__decorators__) {
Ctor.__decorators__ = [];
}
if (typeof index !== 'number') {
index = undefined;
}
Ctor.__decorators__.push(options => factory(options, key, index));
};
}
export function mixins(...Ctors) {
return Vue.extend({ mixins: Ctors });
}
export function isPrimitive(value) {
const type = typeof value;
return value == null || (type !== 'object' && type !== 'function');
}
export function warn(message) {
if (typeof console !== 'undefined') {
console.warn('[vue-class-component] ' + message);
}
}