UNPKG

@coon/utils

Version:
373 lines (368 loc) 9.84 kB
/* * @Author: None * @Date: 2019-11-05 11:29:27 * @LastEditTime: 2020-10-11 07:55:37 * @LastEditors: None * @Description: 工具包 */ type Timeout = ReturnType<typeof setTimeout>; const utils = { /** * @description: 返回对象的类型全小写字符串 * @param {any} v * @return: string */ getType(v: any): string { return Object.prototype.toString.call(v).slice(8, -1).toLowerCase(); }, /** * @description: 是否为某类型 * @param {any} obj * @param {string} type * @return: boolean */ isType(obj: any, type: string): boolean { return utils.getType(obj) === type; }, /** * @description: 是否未定义,undefine或null * @param {any} obj * @return: boolean */ isUndef(obj: any) { return obj === void 0 || obj === null; }, /** * @description: 是否为对象类型 * @param {any} v * @return: boolean */ isObject(v: any): boolean { return typeof v === "object"; }, /** * @description: 是否为数字类型 * @param {any} v * @return: boolean */ isNumber(v: any): boolean { return typeof v === "number"; }, /** * @description: 是否为数组 * @param {any} v * @return: boolean */ isArray(v: any): boolean { return Array.isArray(v); }, /** * @description: 是否为布尔值 * @param {any} v * @return: boolean */ isBoolean(v: any): boolean { return typeof v === "boolean"; }, /** * @description: 是否为函数类型 * @param {any} v * @return: boolean */ isFunction(v: any): boolean { return typeof v === "function"; }, /** * @description: 是否为百分比数值 * @param {any} v * @return: boolean */ isPercent(v: any): boolean { return /%$/.test(v + ""); }, /** * @description: 是否为原对象类型 * @param {any} v * @return: boolean */ isPlainObject(v: any): boolean { return utils.getType(v) === "object"; }, /** * @description: 是否为空(0,'',undefined,null,false,{},[] 都被认为是空) * @param {any} v * @return: boolean */ isEmpty(v: any): boolean { const r = { object: (v: any) => !Object.keys(v).length, array: (v: any) => !v.length, }[utils.getType(v)]; return r === void 0 ? !v : !!r; }, /** * @description: 类数组转数组 * @param {any} v * @return: Array */ toArray(v: any): any[] { return Array.prototype.map.call(v, (n) => n); }, /** * @description: 补零(前置) * @param {number|string} num 原数据 * @param {number} len 总长度:默认2 * @param {string} str 填补字符串:默认'0' * @return: string */ zeroize(num: number | string, len: number = 2, str: string = "0"): string { return num.toString().padStart(len, str); }, /** * @description: 对象按key排序 * @param {Object} obj * @return: Object */ sortObject(obj: object): Object { let tmp = {}; Object.keys(obj) .sort((a, b) => (a > b ? 1 : -1)) .forEach((key) => (tmp[key] = obj[key])); return tmp; }, /** * @description: 把objs的对象属性合并到target中,深层合并,不同于Object.assign的单层合并,常用于函数的option类的参数与默认参数合并 * 最终返回结果就是修改后的target,如果不想有target引用,把{}或null加到第一个参数即可 * @param {Object} target * @param {Array<Object>} objs * @return: Object */ merge(target = {}, ...objs: Array<object>): Object { if (!utils.isPlainObject(target)) target = Object.create(null); if (!objs.length) { return target; } let obj = objs.shift(); for (let key in obj) { let tv = target[key]; let ov = obj[key]; if (utils.isPlainObject(tv) && utils.isPlainObject(ov)) { target[key] = utils.merge({}, target[key], obj[key]); continue; } target[key] = obj[key]; } return objs.length ? utils.merge(target, ...objs) : target; }, /** * @description: 根据单一参数缓存函数返回值 * @param {Function} fn * @return: Function */ cached: (fn: Function): Function => { const cache: {} = Object.create(null); return function (str: string): any { const hit = cache[str]; return hit || (cache[str] = fn(str)); }; }, /** * @description: querystring to json * @param {string} search? * @return: Object */ search2Json: function (search?: string): Object { //无参数时默认返回window.location.search 转换成JSON后的对象 //1个参数时把此参数当成search看待 const obj = Object.create(null); search = search || window.location.search; if (!search) return obj; const arr = search.replace(/^\?/g, "").replace(/\#/g, "").split("&"); for (let i = 0; i < arr.length; i++) { const tmp = arr[i].split("="); obj[tmp[0]] = obj[tmp[0]] ? obj[tmp[0]] instanceof Array ? obj[tmp[0]].concat(tmp[1]) : [obj[tmp[0]], tmp[1]] : tmp[1]; obj[tmp[0]] = decodeURIComponent(obj[tmp[0]]); } return obj; }, //简单倒计时 timers: Object.create(null), /** * @description: 简单倒计时 * @param {string} name * @param {number} timeout? * @param {Function} ticker? * @return: void */ countdown( name: string, timeout?: number, ticker?: Function ): void { let timer: any; if (utils.timers[name]) { timer = utils.timers[name]; } else { class Timer { private tid: number | Timeout = 0; private name: string; private timeout: number; private _timeout: number; constructor(name: string, timeout: number) { this.name = name; this.timeout = this._timeout = timeout; } reset() { this.timeout = this.timeout; } tick(fun?: Function) { var me = this; var tick = function () { me.timeout--; fun && fun(me.timeout); if (me.timeout <= 0) { me.clearInterval(); me.reset(); } }; this.tid && clearInterval(this.tid as Timeout); this.tid = setInterval(tick, 1000); tick(); } clearInterval() { clearInterval(this.tid as Timeout); } } timer = new Timer(name, timeout!); utils.timers[name] = timer; } timer.tick((rest: number) => { ticker && ticker(rest); }); }, /** * @description: sleep * @param {number} duration? * @return: Promise<any> */ sleep(duration = 1000): Promise<any> { return new Promise((resolve) => { setTimeout(resolve, duration); }); }, /** * @description: 时间格式化 * @param {number|striing|Date} d? * @param {string} fmt? * @return: string */ format(d = new Date(), fmt = "yyyy-MM-dd HH:mm:ss") { d = new Date(d); let o = { "M+": d.getMonth() + 1, "d+": d.getDate(), "h+": d.getHours() % 12 == 0 ? 12 : d.getHours() % 12, "H+": d.getHours(), "m+": d.getMinutes(), "s+": d.getSeconds(), "q+": Math.floor((d.getMonth() + 3) / 3), S: d.getMilliseconds(), }; let week = ["日", "一", "二", "三", "四", "五", "六"]; if (/(y+)/.test(fmt)) { fmt = fmt.replace( RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length) ); } if (/(E+)/.test(fmt)) { fmt = fmt.replace( RegExp.$1, (RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? "星期" : "周") : "") + week[d.getDay()] ); } for (let k in o) { if (new RegExp("(" + k + ")").test(fmt)) { fmt = fmt.replace( RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) ); } } return fmt; }, /** * @description: 获取或判断当前平台(android,ios,other) * @param {string} platform? * @return: string */ platform(platform?: string) { const u = navigator.userAgent; const app = navigator.appVersion; const isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //android终端或者uc浏览器 const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 const p = isAndroid ? "android" : isIOS ? "ios" : "other"; return platform ? p === platform.toLowerCase() : p; }, /** * @description: 把类似100s这样的字符串时间解析为以毫秒为单位的数字时间,支持 ms,s,m,h,d * @param {string | number} time * @param {string} u */ parseTime(time: string | number, u: string = 'ms') { const tmap = { ms: 1, s: 1000, m: 1000 * 60, h: 1000 * 60 * 60, d: 1000 * 60 * 60 * 24, } if (typeof time === 'string') { // const [tTime,tu]=time.split(/(?:\d)(?=[a-zA-Z])/); const tu = time.replace(/[\d\.]+/g, '').toLowerCase(); if (tmap.hasOwnProperty(tu)) { u = tu; } time = parseFloat(time); } return tmap[u] * time; }, // 节流 throttle(fn, t = 600, immediate = true) { let sign = false; return (...args) => { if (!sign) { immediate && fn(...args); sign = true; setTimeout(() => { !immediate && fn(...args); sign = false; }, t); } } }, // 防抖 debounce(fn, t = 600, immediate = true) { let sign = false; let tid: Timeout | null = null; return (...args) => { clearTimeout(tid as Timeout); tid = setTimeout(() => { fn(...args); sign = false; }, t); if (!sign) { immediate && fn(...args); sign = true; } } }, }; export default utils;