230 lines
6.0 KiB
TypeScript
230 lines
6.0 KiB
TypeScript
export default class Toolkit {
|
|
|
|
public static isFunction = (val: any) => typeof val === "function";
|
|
public static isArray = Array.isArray;
|
|
public static isString = (val: any) => typeof val === "string";
|
|
public static isSymbol = (val: any) => typeof val === "symbol";
|
|
public static isObject = (val: any) => val !== null && typeof val === "object";
|
|
|
|
public static guid() {
|
|
const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
|
|
return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
|
|
}
|
|
|
|
public static className(...args: any[]) {
|
|
const classes = [];
|
|
for (let i = 0; i < args.length; i++) {
|
|
const value = args[i];
|
|
if (!value) continue;
|
|
if (this.isString(value)) {
|
|
classes.push(value);
|
|
} else if (this.isArray(value)) {
|
|
for (let i = 0; i < value.length; i++) {
|
|
const inner: any = this.className(value[i]);
|
|
if (inner) {
|
|
classes.push(inner);
|
|
}
|
|
}
|
|
} else if (this.isObject(value)) {
|
|
for (const name in value) {
|
|
if (value[name]) {
|
|
classes.push(name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return classes.join(" ");
|
|
}
|
|
|
|
public static isEmpty(obj: any): boolean {
|
|
if (this.isString(obj)) {
|
|
return (obj as string).trim().length === 0;
|
|
}
|
|
if (this.isArray(obj)) {
|
|
return (obj as []).length === 0;
|
|
}
|
|
if (this.isFunction(obj)) {
|
|
return this.isEmpty(obj());
|
|
}
|
|
if (this.isObject(obj)) {
|
|
return obj === undefined || obj === null;
|
|
}
|
|
return obj === undefined || obj === null;
|
|
}
|
|
|
|
public static isNotEmpty(obj: any): boolean {
|
|
return !this.isEmpty(obj);
|
|
}
|
|
|
|
/**
|
|
* ### 延时执行
|
|
*
|
|
* ```js
|
|
* await sleep(1E3)
|
|
* ```
|
|
*
|
|
* @param ms 延时毫秒
|
|
*/
|
|
public static async sleep(ms: number): Promise<unknown> {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
/**
|
|
* 转为数字
|
|
*
|
|
* @param string 字符串
|
|
* @param fallback 如果失败,返回该值
|
|
* @returns 转换后或转换失败数据
|
|
*/
|
|
public static toNumber(string: string, fallback?: number): number {
|
|
if (!string) return fallback as number;
|
|
const number = Number(string);
|
|
return isFinite(number) ? number : fallback as number;
|
|
}
|
|
|
|
/**
|
|
* 异步执行
|
|
*
|
|
* @param event 函数
|
|
*/
|
|
public static async(event: (...args: any[]) => any) {
|
|
setTimeout(event, 0);
|
|
}
|
|
|
|
/**
|
|
* 生成随机数
|
|
*
|
|
* @param min 最小值
|
|
* @param max 最大值
|
|
*/
|
|
public static random(min = 0, max = 100): number {
|
|
return Math.floor(Math.random() * (max + 1 - min)) + min;
|
|
}
|
|
|
|
/**
|
|
* 深克隆对象
|
|
*
|
|
* @param origin 源对象
|
|
* @param target 递归对象
|
|
* @returns 克隆对象
|
|
*/
|
|
public static deepClone(origin: any, target = {} as any) {
|
|
const toString = Object.prototype.toString;
|
|
const arrType = "[object Array]";
|
|
for (const key in origin) {
|
|
if (Object.prototype.hasOwnProperty.call(origin, key)) {
|
|
if (typeof origin[key] === "object" && origin[key] !== null) {
|
|
target[key] = toString.call(origin[key]) === arrType ? [] : {};
|
|
this.deepClone(origin[key], target[key]);
|
|
} else {
|
|
target[key] = origin[key];
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
|
|
public static keyValueString(obj: object, assign: string, split: string): string {
|
|
let result = "";
|
|
Object.entries(obj).forEach(([k, v]) => result += k + assign + v + split);
|
|
return result.substring(0, result.length - split.length);
|
|
}
|
|
|
|
public static toURLArgs(obj?: { [key: string]: any }): string {
|
|
if (!obj) {
|
|
return "";
|
|
}
|
|
const args: string[] = [];
|
|
for (const key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
const value = obj[key];
|
|
if (Array.isArray(value)) {
|
|
value.forEach((item) => {
|
|
args.push(`${encodeURIComponent(key)}=${encodeURIComponent(item)}`);
|
|
});
|
|
} else {
|
|
args.push(`${encodeURIComponent(key)}=${encodeURIComponent(value.toString())}`);
|
|
}
|
|
}
|
|
}
|
|
return args.join("&");
|
|
}
|
|
|
|
public static toObject(map: Map<any, any>): object {
|
|
return Array.from(map.entries()).reduce((acc, [key, value]) => {
|
|
acc[key] = value ?? null;
|
|
return acc;
|
|
}, {} as { [key: string]: string | undefined });
|
|
}
|
|
|
|
public static uuid(): string {
|
|
const char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
const length = [8, 4, 4, 4, 12];
|
|
let result = "";
|
|
for (let i = 0; i < length.length; i++) {
|
|
for (let j = 0; j < length[i]; j++) {
|
|
result += char[this.random(0, char.length - 1)];
|
|
}
|
|
result += "-";
|
|
}
|
|
return result.substring(0, result.length - 1);
|
|
}
|
|
|
|
public static keyFromValue(e: any, value: any): string {
|
|
return Object.keys(e)[Object.values(e).indexOf(value)];
|
|
}
|
|
|
|
// 防抖
|
|
// eslint-disable-next-line
|
|
public static debounce<T extends (...args: any[]) => any>(callback: T, defaultImmediate = true, delay = 600): T & {
|
|
cancel(): void
|
|
} {
|
|
let timerId: ReturnType<typeof setTimeout> | null = null; // 存储定时器
|
|
let immediate = defaultImmediate;
|
|
// 定义一个 cancel 办法,用于勾销防抖
|
|
const cancel = (): void => {
|
|
if (timerId) {
|
|
clearTimeout(timerId);
|
|
timerId = null;
|
|
}
|
|
};
|
|
|
|
const debounced = function (this: ThisParameterType<T>, ...args: Parameters<T>): void {
|
|
const context = this;
|
|
if (timerId) {
|
|
cancel();
|
|
}
|
|
if (immediate) {
|
|
callback.apply(context, args);
|
|
immediate = false;
|
|
timerId = setTimeout(() => {
|
|
immediate = defaultImmediate;
|
|
}, delay);
|
|
} else {
|
|
// 设置定时器,在延迟时间后执行指标函数
|
|
timerId = setTimeout(() => {
|
|
callback.apply(context, args);
|
|
immediate = defaultImmediate;
|
|
}, delay);
|
|
}
|
|
};
|
|
// 将 cancel 方法附加到 debounced 函数上
|
|
(debounced as any).cancel = cancel;
|
|
return debounced as T & { cancel(): void };
|
|
}
|
|
|
|
public static format(template: string, variables: { [key: string]: any }): string {
|
|
return template.replace(/\$\{(\w+)}/g, (_, key) => variables[key]);
|
|
}
|
|
|
|
public static symmetricDiff(arr1: any[], arr2: any[]) {
|
|
const set1 = new Set(arr1);
|
|
const set2 = new Set(arr2);
|
|
|
|
return [
|
|
...arr1.filter(item => !set2.has(item)),
|
|
...arr2.filter(item => !set1.has(item))
|
|
];
|
|
}
|
|
}
|