经常用到的工具函数

整理了一些工作中常用的工具类函数便于Ctrl+v

1.获取地址栏search参数对象

/**
 * 获取参数对象
 * 将name=wzz&password=123转化成{a: 'wzz', password: '123'}
 *
 * @param queryString: String | Undefined 查询字符串
 * @returns Object | Undefined
 */
export function urlQuery(queryString, toLowerCase = false) {
    let params = (queryString && queryString.replace(/^\?/, '')) || window.location.search.replace(/^\?/, '');
    const results = {};
    if (!params) {
        return results;
    }
    params = params.split('&');
    for (let i = 0, len = params.length; i < len; i++) {
        const param = params[i];
        let key, value;
        if (param.includes('=')) {
            const temp = param.split('=');
            key = toLowerCase ? temp[0].toLowerCase() : temp[0];
            value = temp[1];
        } else {
            key = param;
        }
        if (key) {
            results[key] = value || '';
        }
    }
    return results;
}
2.获取当前变量类型
function type(param) {
    return Object.prototype.toString.call(param).slice(8, -1).toLowerCase();
}
3.检测是否是空对象{}
// 是否是对象
function isObject(param) {
    return type(param) === 'object' || param instanceof Object;
}

// 检测是否是空白对象 {}
function isEmptyObject(param) {
    return isObject(param) && Object.keys(param).length === 0;
}
4.判断是否是iphone12机型(其他机型雷同)
/*
 * 通过dpr、width、height 判断不同机型
 * */
function _matchDiffPhone(dpr, width, height) {
    return window.devicePixelRatio === dpr && window.screen.width === width && window.screen.height === height;
}
function isIphone12() {
    // iPhone 12mini 和 iPhone X、iPhone XS一样
    // const isIPhone12Mini = window.devicePixelRatio === 3 && window.screen.width === 375 && window.screen.height === 812;
    // iPhone 12 和 iPhone 12 pro
    const isIPhone12OrPro = _matchDiffPhone(3, 390, 844);
    // iPhone 12 max
    const isIPhone12Max = _matchDiffPhone(3, 428, 926);
    return isIPhone12OrPro || isIPhone12Max;
}
5.动态load需要加载的三方插件
import loadjs from 'loadjs';
/**
 * @description 按需加载外部插件如:highchart、swiper等
 * @param {Object} sdk
 * params对象中包含两个参数插件名和插件url地址,插件名为挂载在window上的名,例如window.Highcharts、window.Swiper等
 * 插件url地址可以从src/api/common/third_sdk_path.js中获取
 * 外部插件处理统一放在src/utils/externals目录下处理
 * */
const pathObj = {};
export function loadjsPromise(sdk = {}) {
    return new Promise(resolve => {
        const globalName = sdk.globalName;
        const path = sdk.path;
        if (!globalName || !path) {
            const msg = `请确保sdk的globalName:${globalName}(全局变量)和path:${path}(sdk路径)存在`;
            console.error(msg);
            throw msg;
        }
        // window上有该对象,则无需再去下载,直接执行后续代码
        if (window[globalName]) {
            resolve();
            return;
        }
        // window上无该插件对象,但是队列中存在,说明多个组件执行了该方法,只需下载最早的那个,其他的存储后续执行函数resolve,用于结果返回后,依次执行
        if (!window[globalName] && pathObj[path]) {
            pathObj[path].delayLists.add(resolve);
        }
        // window上不存在该插件对象且队列中不存在该地址,则表示首次需去下载该插件
        if (!window[globalName] && !pathObj[path]) {
            pathObj[path] = {
                ...sdk,
                delayLists: new Set(),
            };
            loadjs([path], () => {
                // 下载完成,执行首次的执行函数
                resolve();
                const delayLists = pathObj[path]?.delayLists;
                // 如果队列中存在需要执行的函数,则依次执行
                if (delayLists.size > 0) {
                    delayLists.forEach(resolve => {
                        resolve();
                        delayLists.delete(resolve);
                    });
                }
            });
        }
    });
}
6.获取样式
export function getStyle(el, prop) {
    return window.getComputedStyle(el)[prop];
}
7.金额数字转中文
/**
 * 金额数字转中文
 * @param {金额} mount
 * @param {金额单位} ccy
 * @param {中文状态下是否将小数位转换成分,角; 默认true} convertDecimal
 *
 * 转换规则说明:
 * 1,传入非正确数值,返回空字符串
 * 2,传入的数值小于0.01,返回零元
 * 3,0.1 在 convertDecimal 为真情况下,返回壹角; convertDecimal 为假情况下返回 零点壹元
 * 4,0.01 在 convertDecimal 为真情况下,返回壹分; convertDecimal 为假情况下返回 零点零壹元
 * 5,非元单位,小数形式采用点,例如 0.01美元 -> 零点零壹美元
 *
 * 举n个栗子
 * convertAmountToCn(12345) -> 壹万贰仟叁佰肆拾伍元
 * convertAmountToCn(12345.06) -> 壹万贰仟叁佰肆拾伍元零陆分
 * convertAmountToCn(12345.06, 'USD') -> 壹万贰仟叁佰肆拾伍点零陆美元
 * convertAmountToCn(120000.06) -> 壹拾贰万元零陆分
 * convertAmountToCn(120000.06, 'RMB', false) -> 壹拾贰万点零陆元
 * convertAmountToCn(120000.06, 'USD') -> 壹拾贰万点零陆美元
 * convertAmountToCn(1200001.16) -> 壹佰贰拾万零壹元壹角陆分
 * convertAmountToCn(10000.01) -> 壹万元零壹分
 * convertAmountToCn(100010) -> 壹拾万零壹拾元
 */
export function convertAmountToCn(mount, ccy = 'RMB', convertDecimal = true) {
    let money = Number(mount);
    const unit = moneyUnit(ccy);

    // 非正确数值
    if (Number.isNaN(money) || mount === '' || money < 0) {
        return '';
    }

    // 数值小于0.01
    const min = ccy === 'G' ? 0.0001 : 0.01;
    if (money < min) {
        return `零${unit}`;
    }

    // 中文数字
    const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    // 中文单位
    const cnUnits = ['仟', '佰', '拾', '兆', '仟', '佰', '拾', '亿', '仟', '佰', '拾', '万', '仟', '佰', '拾', unit];

    // 将数值拆分成整数位和小数位
    money += '';
    const moneys = /\./.test(money) ? money.split('.') : [money, ''],
        inter = moneys[0] || '',
        deci = moneys[1] || '';

    // 整数位循环替换
    let result = '';
    const unitLength = cnUnits.length;
    const mLength = inter.length;

    for (let i = 0; i < mLength; i += 1) {
        const num = inter[i],
            _unit = cnUnits[unitLength - mLength + i];

        // 数值不是0,正常替换
        // 数值为0,单位是亿,万,元,且目前最后一位不是 '零', '亿', '万' 则直接拼接单位
        // 数值为0,目前最后一位不是零,且后续数值不全为0,拼接零
        if (+num !== 0) {
            result += cnNums[num] + _unit;
        } else if ((unitLength - mLength + i + 1) % 4 === 0) {
            result += _unit;
        }

        if (+num === 0 && !/零$/.test(result) && +inter.substr(i) !== 0) {
            result += '零';
        }
    }

    // 解决 10100000000 零亿,零万问题
    result = result.replace(/(零)(亿|万)/g, ($0, $1, $2) => {
        return $2;
    });

    // 解决 100000111 亿万 问题
    result = result.replace(/亿万/g, '亿');

    // 当整数部分为0时,前面补零
    if (inter === '0' || inter === '') {
        result = `零${result}`;
    }

    // 小数位
    // 单位为元,且有小数,并要求转换时转换为角分
    // 有小数位,不要求转换或其他单位,小数用点表示
    const deci1 = deci[0] - 0,
        deci2 = deci[1] - 0;

    if (convertDecimal && deci.length > 0 && unit === '元') {
        const cn1 = deci1 === 0 ? cnNums[deci1] : `${cnNums[deci1]}角`,
            cn2 = deci2 ? `${cnNums[deci2]}分` : '';

        // 针对 0.n, 0.0n
        if (inter === '0' && deci1 === 0) {
            result = cn2;
        } else if (inter === '0') {
            result = cn1 + cn2;
        } else {
            result += cn1 + cn2;
        }
    } else if (deci.length > 0) {
        // 去除末尾单位
        // 拼接小数位,再加上单位
        result = result.replace(unit, '点');
        // const cn1 = cnNums[deci1],
        //     cn2 = deci2 ? cnNums[deci2] : '';
        // 根据实际小数位循环拼接
        for (let i = 0; i < deci.length; i++) {
            result += cnNums[deci[i] - 0];
        }
        result += unit;
    }

    // 整数加上整
    if (deci.length === 0) {
        result += '整';
    }

    return result;
}
8.防抖和节流
/**
 * 防抖和节流
 * @param {*} fn 函数
 * @param {*} delay 时效
 * @param {*} immediate 是否默认执行
 * @param {*} debounce 是否节流
 * @returns
 */
export const throttle = function (fn, delay, immediate, debounce) {
    let curr = Number(new Date()), // 当前事件
        lastCall = 0,
        lastExec = 0,
        timer = null,
        diff, // 时间差
        context, // 上下文
        args;

    const exec = function () {
        lastExec = curr;
        fn.apply(context, args);
    };
    return function () {
        curr = Number(new Date());
        context = this;
        args = arguments;
        diff = curr - (debounce ? lastCall : lastExec) - delay;
        clearTimeout(timer);
        if (debounce) {
            if (immediate) {
                timer = setTimeout(exec, delay);
            } else if (diff >= 0) {
                exec();
            }
        } else {
            if (diff >= 0) {
                exec();
            } else if (immediate) {
                timer = setTimeout(exec, -diff);
            }
        }
        lastCall = curr;
    };
};
9.转换钞票符号
/**
 * @desc 转换钞票符号
 * */
export function exchangeSymbol(mnyStr) {
    const DICT = {
        CNY: '¥',
        RMB: '¥',
        GBP: '£',
        HKD: 'HKD',
        CHF: 'CHF',
        SGD: 'SGD',
        EUR: '€',
        JPY: 'JPY',
        CAD: 'CAD',
        AUD: 'AUD',
        NZD: 'NZD',
        USD: '$',
        156: '¥',
        840: '$',
    };
    return mnyStr ? DICT[mnyStr] || DICT.RMB : '';
}
10.cookie 封装
/**
 * cookie 封装
 * */
export const cookie = {
    set(key, value, options = {}) {
        if (typeof options.expires === 'number') {
            const days = options.expires,
                t = (options.expires = new Date());

            t.setMilliseconds(t.getMilliseconds() + days * 864e5);
        }

        document.cookie = [
            key,
            '=',
            value,
            options.expires ? `; expires=${options.expires.toUTCString()}` : '',
            options.path ? `; path=${options.path}` : '',
            options.domain ? `; domain=${options.domain}` : '',
            options.secure ? '; secure' : '',
        ].join('');
    },
    get(key) {
        let result,
            i = 0;
        const cookies = document.cookie ? document.cookie.split('; ') : [],
            l = cookies.length;

        for (; i < l; i++) {
            const parts = cookies[i].split('='),
                name = parts.shift(),
                cookie = parts.join('=');

            if (key === name) {
                result = cookie;
                break;
            }
        }

        return result;
    },
    remove(key, options) {
        const e = { expires: -1 };
        this.set(key, '', { ...options, ...e });
    },
};
11.转换日期展示格式 20130907 => 2013-09-07
/**
 * 将固定格式的日期字符串:20130907,转为另外一种日期格式字符串:2013-09-07
 *
 * */
export function convertDate(dateString) {
    if (!dateString || typeof dateString !== 'string') return '';
    return dateString.replace(/(\d{4})(\d{2})(\d{2})/, (x, a, b, c) => {
        return `${a}-${b}-${c}`;
    });
}
12.截取小数点后num位,不四舍五入
/**
 * 截取小数点后num位,不四舍五入
 * @param str 点击物理键返回执行函数
 * @param num 点击物理键返回执行函数
 */
export function getRate(str, num) {
    if (str && num) {
        return (Math.floor((parseFloat(str) * Math.pow(10, +num)).toFixed(6)) / Math.pow(10, +num)).toFixed(num);
    } else {
        return (0).toFixed(num);
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值