整理了一些工作中常用的工具类函数便于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);
}
}