project init

This commit is contained in:
limqhz
2022-11-10 17:13:00 +08:00
commit 4956ed2f1f
113 changed files with 3617 additions and 0 deletions

15
components/common/src/control.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
declare type ControlInstance = {
controlled: boolean;
initValue: any;
set(newVal: any, extObj?: Object, fn?: any): void;
get(): any;
change(newVal: any, customChangeData?: any, customUpdateFn?: any): void;
};
declare type ControlOption = {
valueKey?: string;
defaultValueKey?: string;
changeEventName?: string;
strict?: boolean;
};
declare function useControl(this: any, option?: ControlOption): ControlInstance;
export { ControlOption, ControlInstance, useControl };

View File

@@ -0,0 +1,40 @@
const defaultOption = {
valueKey: 'value',
defaultValueKey: 'defaultValue',
changeEventName: 'change',
strict: true,
};
function useControl(option = {}) {
const { valueKey, defaultValueKey, changeEventName, strict } = Object.assign(Object.assign({}, defaultOption), option);
const props = this.properties || {};
const value = props[valueKey];
const defaultValue = props[strict ? defaultValueKey : valueKey];
let controlled = false;
if (strict && typeof value !== 'undefined' && value !== null) {
controlled = true;
}
const set = (newVal, extObj, fn) => {
this.setData(Object.assign({ [`_${valueKey}`]: newVal }, extObj), fn);
};
return {
controlled,
initValue: controlled ? value : defaultValue,
set,
get: () => {
return this.data[`_${valueKey}`];
},
change: (newVal, customChangeData, customUpdateFn) => {
this.triggerEvent(changeEventName, typeof customChangeData !== 'undefined' ? customChangeData : newVal);
if (controlled) {
return;
}
if (typeof customUpdateFn === 'function') {
customUpdateFn();
}
else {
set(newVal);
}
},
};
}
export { useControl };

15
components/common/src/flatTool.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
export declare const getPrototypeOf: (obj: any) => any;
export declare const isObject: (something: any) => boolean;
export declare const iterateInheritedPrototype: (callback: (proto: Record<string, any>) => boolean | void, fromCtor: any, toCtor: any, includeToCtor?: boolean) => void;
export interface ClassInstanceToObjectOptions {
bindTo?: any;
excludes?: string[];
till?: any;
enumerable?: 0 | boolean;
configurable?: 0 | boolean;
writable?: 0 | boolean;
}
export declare const toObject: (something: any, options?: ClassInstanceToObjectOptions) => {
[key: string]: any;
};
export declare const isPlainObject: (something: any) => boolean;

View File

@@ -0,0 +1,57 @@
export const getPrototypeOf = function (obj) {
return Object.getPrototypeOf ? Object.getPrototypeOf(obj) : obj.__proto__;
};
export const isObject = function isObject(something) {
const type = typeof something;
return something !== null && (type === 'function' || type === 'object');
};
export const iterateInheritedPrototype = function iterateInheritedPrototype(callback, fromCtor, toCtor, includeToCtor = true) {
let proto = fromCtor.prototype || fromCtor;
const toProto = toCtor.prototype || toCtor;
while (proto) {
if (!includeToCtor && proto === toProto)
break;
if (callback(proto) === false)
break;
if (proto === toProto)
break;
proto = getPrototypeOf(proto);
}
};
export const toObject = function toObject(something, options = {}) {
const obj = {};
if (!isObject(something))
return obj;
const excludes = options.excludes || ['constructor'];
const { enumerable = true, configurable = 0, writable = 0 } = options;
const defaultDesc = {};
if (enumerable !== 0)
defaultDesc.enumerable = enumerable;
if (configurable !== 0)
defaultDesc.configurable = configurable;
if (writable !== 0)
defaultDesc.writable = writable;
iterateInheritedPrototype((proto) => {
Object.getOwnPropertyNames(proto).forEach((key) => {
if (excludes.indexOf(key) >= 0)
return;
if (Object.prototype.hasOwnProperty.call(obj, key))
return;
const desc = Object.getOwnPropertyDescriptor(proto, key);
const fnKeys = ['get', 'set', 'value'];
fnKeys.forEach((k) => {
if (typeof desc[k] === 'function') {
const oldFn = desc[k];
desc[k] = function (...args) {
return oldFn.apply(Object.prototype.hasOwnProperty.call(options, 'bindTo') ? options.bindTo : this, args);
};
}
});
Object.defineProperty(obj, key, Object.assign(Object.assign({}, desc), defaultDesc));
});
}, something, options.till || Object, false);
return obj;
};
export const isPlainObject = function isPlainObject(something) {
return Object.prototype.toString.call(something) === '[object Object]';
};

4
components/common/src/index.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
export * from './superComponent';
export * from './flatTool';
export * from './instantiationDecorator';
export * from './control';

View File

@@ -0,0 +1,4 @@
export * from './superComponent';
export * from './flatTool';
export * from './instantiationDecorator';
export * from './control';

View File

@@ -0,0 +1,3 @@
import { SuperComponent } from './superComponent';
export declare const toComponent: (options: Record<string, any>) => Record<string, any>;
export declare const wxComponent: () => (constructor: new () => SuperComponent) => void;

View File

@@ -0,0 +1,98 @@
import { isPlainObject, toObject } from './flatTool';
const RawLifeCycles = ['Created', 'Attached', 'Ready', 'Moved', 'Detached', 'Error'];
const NativeLifeCycles = RawLifeCycles.map((k) => k.toLowerCase());
const ComponentNativeProps = [
'properties',
'data',
'observers',
'methods',
'behaviors',
...NativeLifeCycles,
'relations',
'externalClasses',
'options',
'lifetimes',
'pageLifeTimes',
'definitionFilter',
];
export const toComponent = function toComponent(options) {
if (options.properties) {
Object.keys(options.properties).forEach((k) => {
let opt = options.properties[k];
if (!isPlainObject(opt)) {
opt = { type: opt };
}
options.properties[k] = opt;
});
}
if (!options.methods)
options.methods = {};
if (!options.lifetimes)
options.lifetimes = {};
const inits = {};
Object.getOwnPropertyNames(options).forEach((k) => {
const desc = Object.getOwnPropertyDescriptor(options, k);
if (!desc)
return;
if (NativeLifeCycles.indexOf(k) < 0 && typeof desc.value === 'function') {
Object.defineProperty(options.methods, k, desc);
delete options[k];
}
else if (ComponentNativeProps.indexOf(k) < 0) {
inits[k] = desc;
}
else if (NativeLifeCycles.indexOf(k) >= 0) {
options.lifetimes[k] = options[k];
}
});
if (Object.keys(inits).length) {
const oldCreated = options.lifetimes.created;
const oldAttached = options.lifetimes.attached;
const { controlledProps = [] } = options;
options.lifetimes.created = function (...args) {
Object.defineProperties(this, inits);
if (oldCreated)
oldCreated.apply(this, args);
};
options.lifetimes.attached = function (...args) {
if (oldAttached)
oldAttached.apply(this, args);
controlledProps.forEach(({ key }) => {
const defaultKey = `default${key.replace(/^(\w)/, (m, m1) => m1.toUpperCase())}`;
const props = this.properties;
if (props[key] == null && props[defaultKey] != null) {
this.setData({
[key]: props[defaultKey],
});
this._controlled = true;
}
});
};
options.methods._trigger = function (evtName, detail, opts) {
const target = controlledProps.find((item) => item.event == evtName);
if (target) {
const { key } = target;
if (this._controlled) {
this.setData({
[key]: detail[key],
});
}
}
this.triggerEvent(evtName, detail, opts);
};
}
return options;
};
export const wxComponent = function wxComponent() {
return function (constructor) {
class WxComponent extends constructor {
}
const current = new WxComponent();
current.options = current.options || {};
if (current.options.addGlobalClass === undefined) {
current.options.addGlobalClass = true;
}
const obj = toComponent(toObject(current));
Component(obj);
};
};

View File

@@ -0,0 +1,19 @@
/// <reference types="miniprogram-api-typings" />
export interface ComponentsOptionsType extends WechatMiniprogram.Component.ComponentOptions {
styleIsolation?: 'isolated' | 'apply-shared' | 'shared' | 'page-isolated' | 'page-apply-shared' | 'page-shared';
}
export interface RelationsOptions {
[componentName: string]: WechatMiniprogram.Component.RelationOption;
}
export interface SuperComponent<D = {}, P = {}, M = {}> extends WechatMiniprogram.Component.Lifetimes, WechatMiniprogram.Component.OtherOption, WechatMiniprogram.Component.InstanceMethods<D> {
properties: P;
data: D;
options: ComponentsOptionsType;
methods: M | Record<string, (...args: any[]) => any>;
$global: Function;
[x: string]: any;
}
export declare class SuperComponent<D = {}, P = {}, M = {}> {
readonly app: any;
constructor();
}

View File

@@ -0,0 +1,5 @@
export class SuperComponent {
constructor() {
this.app = getApp();
}
}