UNPKG

mofang-mopai-utils

Version:

Use it in Mopai system

325 lines (307 loc) 8.36 kB
/** * 魔方魔派系统工具包 */ import MofangMopaiCalculator from "./mofang-mopai-calculator" import MofangCalculatorV2 from "./mofang-calculator-v2" /** * 深拷贝 * @param data { any } * @returns any */ function deepCopy<T>(data: T): T { let d: any if (typeof data === 'object') { if (Array.isArray(data)) { d = [] for (let i = 0, len = data.length; i < len; i++) d[i] = deepCopy(data[i]) } else if (data === null) { d = null } else if (data.constructor === RegExp) { d = data } else if (Object.keys(data).length) { d = {} for (const key in data) { const k = key d[k] = deepCopy(data[k]) } } else { d = data } } else { d = data } return d } /** * 防抖 * @param fn {Function} * @param delay {number} * @returns {Function} */ function debounce<T = Function>(fn: T, delay: number = 200): T { let timer: ReturnType<typeof setTimeout> if (typeof fn !== 'function') { throw new TypeError('类型错误,传入函数不是一个方法') } return function (this: unknown) { const args = arguments clearTimeout(timer) timer = setTimeout(() => { fn.apply(this, args) }, delay) } as any } /** * 节流 * @param fn - The function to be throttled. * @param delay - The number of milliseconds to delay. * @returns A new throttled function. */ function throttle<T = Function>(fn: T, delay: number = 200): T { let isRunning: boolean = false if (typeof fn !== 'function') { throw new TypeError('类型错误,传入函数不是一个方法') } return function (this: unknown) { const args = arguments if (isRunning) return isRunning = true fn.apply(this, args) setTimeout(() => { isRunning = false }, delay) } as any } /** * 去重 * Returns a new array without duplicate elements. * @param arr - The array to remove duplicates from. * @returns A new array without duplicate elements. */ function unique<T>(arr: []): T { if (!Array.isArray(arr)) { throw new TypeError('类型错误,传入参数不是一个Array') } let list: any[] = [] for (const value of arr) { if (typeof value === "object" && value !== null) { if (list.every((v) => JSON.stringify(v) !== JSON.stringify(value))) { list.push(value); } } else if (value !== undefined && list.indexOf(value) === -1) { list.push(value); } } return list as T } /** * Flattens an array of arrays into a single level array. * * @param arr - the array to flatten * @returns a new array with all the elements of the original array, regardless of their nesting level */ function flat<T>(arr: T): T { if (!Array.isArray(arr)) { throw new TypeError('类型错误,传入参数不是一个Array') } return arr.reduce((prev, cur: any) => { return prev.concat(Array.isArray(cur) ? flat(cur) : cur) }, []) } /** * 过滤掉object中的无效键值 * @param data object * @returns object */ function getValidObject<T = Record<string, any>>(data: T): T { if (typeof data !== 'object' && Object.prototype.toString.call(data) !== '[object Object]') { throw new TypeError('类型错误,传入参数不是一个Object') } let obj = {} as T for (const key in data) { const value: any = data[key] let isEnable = false if (typeof value === 'object' && value !== null) { isEnable = isEmpty(value) } else { isEnable = value || value === 0 } isEnable && (obj[key] = value) } return obj } /** * 基于前端的计算器 * @param formula { string } 计算公式 * @returns number 计算结果 * * @example * calc('1.2+0.3*0.02+4') // return 5.206 */ function calc(formula: string): number{ const ca = new MofangMopaiCalculator(formula) return ca.get() } function calcV2(number1: number, number2: number, method: string): number { return MofangCalculatorV2(number1, number2, method) } function getUUID(len: number = 32): string { const chars = Array.from('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz') const uuid: string[] = [] const radix = len for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] return uuid.join('') } /** * 判断Pbject或Array是否为空 * @param data { object | array } * @returns boolean */ function isEmpty(data: Object): boolean { if (Array.isArray(data)) { return data.length === 0 } else { return Object.keys(data).length === 0 } } function isNotEmpty(data: Object): boolean { return !isEmpty(data) } /** * 格式化数组分组 * @param arr * @returns array */ function zip<T>(...args: any): T { if (!args || !Array.isArray(args) || args.some(item => !Array.isArray(item))) { throw new TypeError('类型错误,传入参数错误') } const resultList = [] as any[] args.forEach((list: [], listIdx: number) => { list.forEach((item: any, itemIdx: number) => { if (!resultList[itemIdx]) resultList[itemIdx] = [] resultList[itemIdx][listIdx] = item }) }) return resultList as T } function unzip<T>(...args: any): T { if (!args || !Array.isArray(args) || args.some(item => !Array.isArray(item))) { throw new TypeError('类型错误,传入参数错误') } let len = 0 const resultList = [] as any[] args.forEach((list: [], listIdx: number) => { if (len === 0) { len = list.length } if (len !== list.length) { throw new TypeError('they are not same length Array in list') } list.forEach((item: any, itemIdx: number) => { if (!resultList[itemIdx]) resultList[itemIdx] = [] resultList[itemIdx][listIdx] = item }) }) return resultList as T } /** * 判断object|array中是否存在指定参数 * @param keyname { string } * @param data { object | array } * @returns boolean */ function isExist(keyname: string, data: Object): boolean { if (Array.isArray(data)) { return data.indexOf(keyname) > -1 } else { const keys = Object.keys(data) return keys.indexOf(keyname) > -1 } } /** * 判断数据类型 * @param data { any } * @returns string 数据的类型,小写 */ function whichTypeOf(data: any): string { if (typeof data === 'object') { return Array.isArray(data) ? 'array' : Object.prototype.toString.call(data) === '[object Object]' ? 'object' : 'unknownType' } else { return typeof data } } /** * 动态置入script标签,引用js文件 * @param src { string } js文件链接 * @param cb { function } 状态回调 * @returns promise 状态回调 */ function loadJs(src: string, cb?: Function): Promise<string> { const script = document.createElement('script') script.type = 'text/javascript' script.src = src document.getElementsByTagName('head')[0].appendChild(script) return new Promise((resolve, rejects) => { script.onload = () => { cb?.('ok') resolve('ok') } script.onerror = () => { cb?.('error') rejects('error') } }) } const toolkit = { deepCopy, debounce, throttle, unique, getValidObject, calc, calcV2, getUUID, isEmpty, isNotEmpty, zip, unzip, isExist, whichTypeOf, loadJs, flat, } declare const window: Window interface Window { [key: string]: any } /** * 设置window全局utils * @param keyname { string } 键名 [default: $utils] */ function setGlobalUtils(keyname: string) { let key = keyname || '$utils' if (window as Window) { !window[key] && (window[key] = toolkit) } } export { deepCopy, debounce, throttle, unique, getValidObject, calc, calcV2, getUUID, isEmpty, isNotEmpty, zip, unzip, isExist, whichTypeOf, loadJs, setGlobalUtils, flat, toolkit as default }