/**
* 节流: 在给定时间内只有第一次的操作会返回结果, 结合了防抖的思路:在delay时间内生成定时器,一旦到了delay的时间就返回结果, 当用户只点击了一次的时候,在delay时间后得到结果, 当用户点击了多次的时候,在delay时间后得到第一次的结果,其余的被节流阀忽视掉
* @param {Function} fn 要包装的回调函数
* @param {number} delay 延迟时间,单位ms,默认500
* @return {Function} 被节流函数劫持的新的函数
*/
function throttle(fn, delay = 500) {
let last = 0;
let timer = null;
return function () {
let args = arguments;
let now = +new Date();
let context = this;
if (now - last < delay) {
clearTimeout(timer);
timer = setTimeout(() => {
last = now;
fn.apply(context, args);
}, delay);
} else {
last = now;
fn.apply(context, args);
}
}
}
/**
* 防抖: 在delay时间后得到结果, 如果没等到delay的时间一直触发则永远也得不到结果
* @param {Function} fn 要包装的回调函数
* @param {number} delay 延迟时间,单位ms,默认500
* @return {Function} 被防抖函数劫持的新的函数
*/
function debounce(fn, delay = 500) {
let timer = null;
return function () {
let args = arguments;
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
/**
* 类型检测函数
* 为typeof关键字的增强版,可以准确判断null,date类型
* 原理是使用V8引擎最初的toString方法观察数据类型
* @param {Object} obj 任意对象,例如null,undefined,date
* @return {String} 类型的全小写字符串
*/
function type(obj) {
return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
/**
* 获取地图上两点间距离。单位:米
* @param {lat1} 第一个点的纬度
* @param {lon1} 第一个点的经度
* @param {lat2} 第二个点的纬度
* @param {lon2} 第二个点的经度
*/
export function getDistance(lat1, lon1, lat2, lon2) {
const radLat1 = (lat1 * Math.PI) / 180.0;
const radLat2 = (lat2 * Math.PI) / 180.0;
const a = radLat1 - radLat2;
const b = (lon1 * Math.PI) / 180.0 - (lon2 * Math.PI) / 180.0;
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * 6378137;
s = Math.round(s * 10000) / 10000;
return s;
}
// 有时在微信小程序中需要对组件的样式进行修改
export default {
options: { styleIsolation: 'shared' }
}
// 身份证号
function isIdCard(str) {
return /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(str);
}
// 手机号
function isPhoneNumber(str) {
return /^1[3456789]\d{9}$/.test(str);
}
// 手机号脱敏
function desensitization(phone) {
const regexp = /(\d{3})\d{4}(\d{4})/
return phone.replace(regexp, '$1****$2');
}
//const phone = "13412345678"
//phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
// 空白判断
function blank(v) {
const regexp = /^\s+$/
return regexp.test(v)
}
// 是否合法的http/https域名
function isHttpUrl(str) {
const regexp = /^(http|https):\/\/[^\s]+$/
return regexp.test(str)
}
// Emai验证
function email(v) {
const regexp = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
return regexp.test(v)
}
// 对数组分组
function groupBy(list, propName) {
return list.reduce((acc, item) => {
const key = item[propName];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item);
return acc;
}, {});
}
// 深拷贝对象
function deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== 'object') return obj;
if (obj instanceof Date) {
let date = new Date();
date.setTime(obj.getTime());
return date;
}
if (obj instanceof RegExp) {
let re = new RegExp(obj.source);
re.lastIndex = obj.lastIndex;
return re;
}
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
// 提取若干数组中指定字段组合成一个新数组
function extractProps(arr, prop) {
return arr.map((item) => item[prop]);
}
// 提取对象中的指定的属性,返回一个新对象
function pickProps(obj, props) {
if (typeof obj !== 'object') {
return obj;
}
const newObj = {};
props.forEach((prop) => {
newObj[prop] = obj[prop];
});
return newObj;
}
// 姓名除了姓显示其他
function formatName(str) {
return str.substring(0, 1) + new Array(str.length).join('*');
}
// 去除字符串前后空格
function trim(str) {
return String.prototype.trim.call(str);
}
// 日期时间处理
export function timeFun(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
}
// 小于10补0
function repair(str) {
if (Number(str) < 10) return `0${str}`
else return `${str}`
}
// 将年月日时分秒分割为年月日
function yearSplit(str) {
if (str) return str.slice(0, 10)
}
// 将年月日时分秒分割为时分秒
function hourSplit(str) {
if (str) return str.slice(11)
}
// 时间日期处理-针对评论留言等
function timeTranslateAll(e) {
const now = new Date();
const date = new Date(e);
if(((now.getTime()/1000)-(e/1000))<0) {
return date.getFullYear()+"年"+repair(date.getMonth()+1)+"月"+repair(date.getDate())+"日 "+repair(date.getHours())+":"+repair(date.getMinutes());
}
if(((now.getTime()/1000)-(e/1000)) < 60) {
return "刚刚";
}else if(((now.getTime()/1000)-(e/1000))<3600) {
return parseInt((now.getTime()/1000-(e/1000))/60)+"分钟前";
}else if(((now.getTime()/1000)-(e/1000))<3600*24) {
return parseInt((now.getTime()/1000-(e/1000))/3600)+"小时前";
}else if(((now.getTime()/1000)-(e/1000))<3600*24*30) {
return parseInt((now.getTime()/1000-(e/1000))/(3600*24))+"天前";
}else if(((now.getTime()/1000)-(e/1000))<3600*24*30*12) {
return parseInt((now.getTime()/1000-(e/1000))/(3600*24*30))+"月前";
}else {
return date.getFullYear()+"年"+repair(date.getMonth()+1)+"月"+repair(date.getDate())+"日 "+repair(date.getHours())+":"+repair(date.getMinutes());
}
}
// 获取url参数
function urlParams(url) {
let params = {}
if (url.indexOf('?') > -1) {
let strs = url.split('?')[1].split('&')
strs.forEach((d) => {
let ds = d.split('=')
params[ds[0]] = ds[1]
})
}
return params
}
// 百分比
function rateFormat(num) {
return `${this.decimalFormat(num * 100)}%`
}
// 小数点则保留长度,默认2位
function decimalFormat(num, dit = 2) {
num = Number(num)
let nums = (num || 0).toString()
let ln = nums.split('.')[1]
ln = (ln && ln.length) || 0
return (num || 0).toFixed(ln >= dit ? dit : ln)
}
// 小于一万保留最多两位小数返回,大于万和百万则保留4位小数并格式化返回
function moneyFormat(num) {
num = Number(num)
if (!num) return 0
if (num < Math.pow(10, 4)) return this.decimalFormat(num)
if (num < Math.pow(10, 6))
return this.decimalFormat(num / Math.pow(10, 4), 4) + '万' //万
return this.decimalFormat(num / Math.pow(10, 6), 4) + '百万' //百万
}
// * @description 格式化金额
// * @param number:要格式化的数字
// * @param decimals:保留几位小数 默认0位
// * @param decPoint:小数点符号 默认.
// * @param thousandsSep:千分位符号 默认为,
function moneyFormatTwo(number, decimals = 2, decPoint = '.', thousandsSep = ',') {
number = (number + '').replace(/[^0-9+-Ee.]/g, '')
let n = !isFinite(+number) ? 0 : +number
let prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
let sep = typeof thousandsSep === 'undefined' ? ',' : thousandsSep
let dec = typeof decPoint === 'undefined' ? '.' : decPoint
let s = ''
let toFixedFix = function (n, prec) {
let k = Math.pow(10, prec)
return '' + Math.ceil(n * k) / k
}
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
let re = /(-?\d+)(\d{3})/
while (re.test(s[0])) {
s[0] = s[0].replace(re, '$1' + sep + '$2')
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
// 数组分割成字符串
function arrayToString(array) {
let strs = '';
if(array && array instanceof Array) {
strs = array.join(',');
}
return strs;
}
// 字符串分割成数组
function stringToArray(str) {
let array = []
if(str && typeof str === 'string') {
array = str.split(',')
}
return array
}
/**
* 是否车牌号
*/
function carNo(value) {
// 新能源车牌
const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
// 旧车牌
const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
if (value.length === 7) {
return creg.test(value)
} if (value.length === 8) {
return xreg.test(value)
}
return false
}
/**
* 金额,只允许2位小数
*/
function amount(value) {
// 金额,只允许保留两位小数
return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
}
/**
* 中文
*/
function chinese(value) {
const reg = /^[\u4e00-\u9fa5]+$/gi
return reg.test(value)
}
/**
* 只能输入字母
*/
function letter(value) {
return /^[a-zA-Z]*$/.test(value)
}
/**
* 只能是字母或者数字
*/
function enOrNum(value) {
// 英文或者数字
const reg = /^[0-9a-zA-Z]*$/g
return reg.test(value)
}
/**
* 验证是否包含某个值
*/
function contains(value, param) {
return value.indexOf(param) >= 0
}
/**
* 验证一个值范围[min, max]
*/
function range(value, param) {
return value >= param[0] && value <= param[1]
}
/**
* 验证一个长度范围[min, max]
*/
function rangeLength(value, param) {
return value.length >= param[0] && value.length <= param[1]
}
/**
* 是否固定电话
*/
function landline(value) {
const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
return reg.test(value)
}
/**
* 判断是否为空
*/
function empty(value) {
switch (typeof value) {
case 'undefined':
return true
case 'string':
if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
break
case 'boolean':
if (!value) return true
break
case 'number':
if (value === 0 || isNaN(value)) return true
break
case 'object':
if (value === null || value.length === 0) return true
for (const i in value) {
return false
}
return true
}
return false
}
/**
* 是否json字符串
*/
function jsonString(value) {
if (typeof value === 'string') {
try {
const obj = JSON.parse(value)
if (typeof obj === 'object' && obj) {
return true
}
return false
} catch (e) {
return false
}
}
return false
}
/**
* 是否数组
*/
function array(value) {
if (typeof Array.isArray === 'function') {
return Array.isArray(value)
}
return Object.prototype.toString.call(value) === '[object Array]'
}
/**
* 是否对象
*/
function object(value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
/**
* 是否短信验证码
*/
function code(value, len = 6) {
return new RegExp(`^\\d{${len}}$`).test(value)
}
/**
* 是否函数方法
* @param {Object} value
*/
function func(value) {
return typeof value === 'function'
}
/**
* 验证整数
*/
function digits(value) {
return /^\d+$/.test(value)
}
/** 是否图片格式
* @param {Object} value
*/
function image(value) {
const newValue = value.split('?')[0]
const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i
return IMAGE_REGEXP.test(newValue)
}
/**
* 是否视频格式
* @param {Object} value
*/
function video(value) {
const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i
return VIDEO_REGEXP.test(value)
}
之后再有新的再添加~