时间戳转时间类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export const formatDateTime = (value = Date.now(), format = "Y-M-D h:m:s") => {
if (["null", null, "undefined", undefined, ""].includes(value)) return "";
// ios 和 mac 系统中,带横杆的字符串日期是格式不了的,这里做一下判断处理
if (typeof value === "string" && new Date(value).toString() === "Invalid Date") {
value = value.replace(/-/g, "/");
}
const formatNumber = n => `0${n}`.slice(-2);
const date = new Date(value);
const formatList = ["Y", "M", "D", "h", "m", "s"];
const resultList = [];
resultList.push(date.getFullYear().toString());
resultList.push(formatNumber(date.getMonth() + 1));
resultList.push(formatNumber(date.getDate()));
resultList.push(formatNumber(date.getHours()));
resultList.push(formatNumber(date.getMinutes()));
resultList.push(formatNumber(date.getSeconds()));
for (let i = 0; i < resultList.length; i++) {
format = format.replace(formatList[i], resultList[i]);
}
return format;
}

随机返回true或false

1
2
3
4
export const randomsort = function (a, b) {
return Math.random() > .5 ? -1 : 1;
//用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1
}

日期转时间戳

1
2
3
4
5
export const dateTimeStamp = function (data) {
let date = new Date(data);
let timestamp = date.getTime()
return timestamp
}

获取html字符串中图片src

第一张图片src

1
2
3
4
5
6
7
export const getFirstPic = (str) => {
let data = ''
str.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/, function (match, capture) {
data = capture
})
return data
}

所有图片的src

1
2
3
4
5
6
7
8
9
export const getimgsrc = (htmlstr) => {
var reg = /<img.+?src=('|")?([^'"]+)('|")?(?:\s+|>)/gim
var arr = []
var tem = null
while (tem = reg.exec(htmlstr)) {
arr.push(tem[2])
}
return arr
}

unicode转中文

1
2
3
4
5
6
7
8
9
export const exchangeUnicode = (str) => {
str = JSON.stringify(str)
str = str.replace(/(\\u)(\w{1,4})/gi, ($0) => {
return (String.fromCharCode(parseInt((escape($0).replace(/(%5Cu)(\w{1,4})/g, "$2")),
16)));
});
str = JSON.parse(str);
return str;
}

获取指定日期n个月后日期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
export const getNextMonthDay = (date, monthNum) => {
let dateArr = date.split('-');
let year = dateArr[0]; //获取当前日期的年份
let month = dateArr[1]; //获取当前日期的月份
let day = dateArr[2]; //获取当前日期的日
let days = new Date(year, month, 0);
days = days.getDate(); //获取当前日期中的月的天数
let year2 = year;
let month2 = parseInt(month) + parseInt(monthNum);
if (month2 > 12) {
year2 = parseInt(year2) + parseInt((parseInt(month2) % 12 == 0 ? (parseInt(month2) / 12) - 1 : parseInt(month2) / 12));
month2 = parseInt(month2) % 12;
if (month2 == 0) {
month2 = 12;
}
}
let day2 = day;
let days2 = new Date(year2, month2, 0);
days2 = days2.getDate();
if (day2 > days2) {
day2 = days2;
}
if (month2 < 10) {
month2 = '0' + month2;
}

let t2 = year2 + '-' + month2 + '-' + day2;
return t2;
}

计算天数差

1
2
3
4
5
6
7
8
9
export const dateDiff = (sDate1, sDate2) => { //sDate1和sDate2是2002-12-18格式 
let aDate, oDate1, oDate2, iDays
aDate = sDate1.split("-")
oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) //转换为12-18-2002格式
aDate = sDate2.split("-")
oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24) //把相差的毫秒数转换为天数
return iDays
}

根据经纬度计算距离

1
2
3
4
5
6
7
8
9
10
11
export const distance = (la1, lo1, la2, lo2) => {
var La1 = la1 * Math.PI / 180.0;
var La2 = la2 * Math.PI / 180.0;
var La3 = La1 - La2;
var Lb3 = lo1 * Math.PI / 180.0 - lo2 * Math.PI / 180.0;
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) + Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(Lb3 / 2), 2)));
s = s * 6378.137;
s = Math.round(s * 10000) / 10000;
s = s.toFixed(2);
return s;
}

根据时间判断周几

1
2
3
4
5
export const weekDay = (date) => {
let weekArray = ["日", "一", "二", "三", "四", "五", "六"];
let week = weekArray[new Date(date).getDay()];
return `周${week}`
}

倒计时计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//参数为毫秒数
export const countDownCal = function (times) {
var d, h, m, s, ms;
if (times >= 0) {
d = Math.floor(times / 1000 / 60 / 60 / 24);
h = Math.floor(times / 1000 / 60 / 60 % 24);
m = Math.floor(times / 1000 / 60 % 60);
s = Math.floor(times / 1000 % 60);
// ms = Math.floor(times % 1000);
// if(ms < 100) {
// ms = "0" + ms;
// }
if (d < 10) {
d = "0" + d;
}
if (s < 10) {
s = "0" + s;
}
if (m < 10) {
m = "0" + m;
}
if (h < 10) {
h = "0" + h;
}
let result = {
day: d,
hours: h,
minute: m,
seconds: s
}
return result
} else {
return
}

}

判断是否为非法字符

1
2
3
4
5
6
7
8
export const checkCode = (code) => {
let patrn = /[`~!@#$%^&*()_+<>?:"{},.|=^《》?!、;……’‘“”【】。,:——/;'[\]]/gim;
if (patrn.test(code)) {
return false;
} else {
return true
}
}

手机号格式化

1
2
3
4
5
6
7
export const formatPhone = (phone) => {
if (!phone || typeof phone !== 'string') {
return
}
let mphone = phone.substring(0, 3) + '****' + phone.substring(7);
return mphone
}

获取随机颜色

1
2
3
4
5
6
7
8
9
10
11
12
export const getRandomColor = () => {
//定义数组,值为1—f
let num = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
//颜色的值为16进制并且开头为#,
let str = "#";
//我们需要的是一个6位的十六进制所以循环6次
for (var i = 0; i < 6; i++) {
//随机产生的数做数组的索引,索引值只能为整数所以需要转换为整型通过索引获得数组的值,
str += num[Math.floor(Math.random() * 16)];
}
return str;
}

格式化时间 XXS变成 X分X秒

1
2
3
4
5
6
export const formatSeconds = (s) => {
let m = Math.floor(s / 60)
let mm = s % 60
return `${m}${mm}秒`

}

星期转中文

1
2
3
4
5
export const numToChinese = (num) => {
let map = ['日', '一', '二', '三', '四', '五', '六']

return map[num]
}

去掉对象里的空值属性

1
2
3
4
5
6
7
8
9
10
11
12
13
export const formatObj = (obj) => {
if (obj instanceof Object) {
for (let k in obj) {
if (obj[k] === '' || JSON.stringify(obj[k]) === '[]' || obj[k] === null || JSON.stringify(obj[k]) === '{}') {
delete obj[k]
}
}
return obj
} else {
return {}
}

}

校验数据类型

1
2
3
export const typeOf = function (obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
}

防抖

1
2
3
4
5
6
7
export const debounce = (() => {
let timer = null
return (callback, wait = 800) => {
timer && clearTimeout(timer)
timer = setTimeout(callback, wait)
}
})()

节流

1
2
3
4
5
6
7
8
9
10
export const throttle = (() => {
let last = 0
return (callback, wait = 800) => {
let now = +new Date()
if (now - last > wait) {
callback()
last = now
}
}
})()

手机号脱敏

1
2
3
export const hideMobile = (mobile) => {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}

开启全屏

1
2
3
4
5
6
7
8
9
10
11
export const launchFullscreen = (element) => {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
}
}

关闭全屏

1
2
3
4
5
6
7
8
9
10
11
export const exitFullscreen = () => {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
}

大小写转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//   str 待转换的字符串
// type 1-全大写 2-全小写 3-首字母大写

export const turnCase = (str, type) => {
switch (type) {
case 1:
return str.toUpperCase()
case 2:
return str.toLowerCase()
case 3:
//return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
return str[0].toUpperCase() + str.substring(1).toLowerCase()
default:
return str
}
}

解析url参数

1
2
3
4
5
6
7
8
export const getSearchParams = () => {
const searchPar = new URLSearchParams(window.location.search)
const paramsObj = {}
for (const [key, value] of searchPar.entries()) {
paramsObj[key] = value
}
return paramsObj
}

判断设备是Android或IOS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/** 
* 1: ios
* 2: android
* 3: 其它
*/
export const getOSType = () => {
let u = navigator.userAgent,
app = navigator.appVersion;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if (isIOS) {
return 1;
}
if (isAndroid) {
return 2;
}
return 3;
}

数组对象根据字段去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// arr 要去重的数组
// key 根据去重的字段名
export const uniqueArrayObject = (arr = [], key = 'id') => {
if (arr.length === 0) return
let list = []
const map = {}
arr.forEach((item) => {
if (!map[item[key]]) {
map[item[key]] = item
}
})
list = Object.values(map)

return list
}

滚动到页面顶部

1
2
3
4
5
6
7
export const scrollToTop = () => {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}

滚动到元素位置

1
2
3
4
5
export const smoothScroll = element => {
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};

uuid

1
2
3
4
5
6
export const uuid = () => {
const temp_url = URL.createObjectURL(new Blob())
const uuid = temp_url.toString()
URL.revokeObjectURL(temp_url) //释放这个url
return uuid.substring(uuid.lastIndexOf('/') + 1)
}

金额格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// {number} number:要格式化的数字
// {number} decimals:保留几位小数
// {string} dec_point:小数点符号
// {string} thousands_sep:千分位符号
export const moneyFormat = (number, decimals, dec_point, thousands_sep) => {
number = (number + '').replace(/[^0-9+-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
const dec = typeof dec_point === 'undefined' ? '.' : dec_point
let s = ''
const toFixedFix = function (n, prec) {
const k = Math.pow(10, prec)
return '' + Math.ceil(n * k) / k
}
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
const 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)
}

本地存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
export class MyCache {
constructor(isLocal = true) {
this.storage = isLocal ? localStorage : sessionStorage
}

setItem(key, value) {
if (typeof (value) === 'object') value = JSON.stringify(value)
this.storage.setItem(key, value)
}

getItem(key) {
try {
return JSON.parse(this.storage.getItem(key))
} catch (err) {
return this.storage.getItem(key)
}
}

removeItem(key) {
this.storage.removeItem(key)
}

clear() {
this.storage.clear()
}

key(index) {
return this.storage.key(index)
}

length() {
return this.storage.length
}
}

下载文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// api 接口
// params 请求参数
// fileName 文件名
const downloadFile = (api, params, fileName, type = 'get') => {
axios({
method: type,
url: api,
responseType: 'blob',
params: params
}).then((res) => {
let str = res.headers['content-disposition']
if (!res || !str) {
return
}
let suffix = ''
// 截取文件名和文件类型
if (str.lastIndexOf('.')) {
fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
suffix = str.substring(str.lastIndexOf('.'), str.length)
}
// 如果支持微软的文件下载方式(ie10+浏览器)
if (window.navigator.msSaveBlob) {
try {
const blobObject = new Blob([res.data]);
window.navigator.msSaveBlob(blobObject, fileName + suffix);
} catch (e) {
console.log(e);
}
} else {
// 其他浏览器
let url = window.URL.createObjectURL(res.data)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName + suffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href);
}
}).catch((err) => {
console.log(err.message);
})
}

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。
export const clone = parent => {
// 判断类型
const isType = (obj, type) => {
if (typeof obj !== "object") return false;
const typeString = Object.prototype.toString.call(obj);
let flag;
switch (type) {
case "Array":
flag = typeString === "[object Array]";
break;
case "Date":
flag = typeString === "[object Date]";
break;
case "RegExp":
flag = typeString === "[object RegExp]";
break;
default:
flag = false;
}
return flag;
};

// 处理正则
const getRegExp = re => {
var flags = "";
if (re.global) flags += "g";
if (re.ignoreCase) flags += "i";
if (re.multiline) flags += "m";
return flags;
};
// 维护两个储存循环引用的数组
const parents = [];
const children = [];

const _clone = parent => {
if (parent === null) return null;
if (typeof parent !== "object") return parent;

let child, proto;

if (isType(parent, "Array")) {
// 对数组做特殊处理
child = [];
} else if (isType(parent, "RegExp")) {
// 对正则对象做特殊处理
child = new RegExp(parent.source, getRegExp(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (isType(parent, "Date")) {
// 对Date对象做特殊处理
child = new Date(parent.getTime());
} else {
// 处理对象原型
proto = Object.getPrototypeOf(parent);
// 利用Object.create切断原型链
child = Object.create(proto);
}

// 处理循环引用
const index = parents.indexOf(parent);

if (index != -1) {
// 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
return children[index];
}
parents.push(parent);
children.push(child);

for (let i in parent) {
// 递归
child[i] = _clone(parent[i]);
}

return child;
};
return _clone(parent);
};

模糊搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
// list 原数组
// keyWord 查询的关键词
// attribute 数组需要检索属性
export const fuzzyQuery = (list, keyWord, attribute = 'name') => {
const reg = new RegExp(keyWord)
const arr = []
for (let i = 0; i < list.length; i++) {
if (reg.test(list[i][attribute])) {
arr.push(list[i])
}
}
return arr
}

遍历树节点

1
2
3
4
5
6
7
8
export const foreachTree = (data, callback, childrenName = 'children') => {
for (let i = 0; i < data.length; i++) {
callback(data[i])
if (data[i][childrenName] && data[i][childrenName].length > 0) {
foreachTree(data[i][childrenName], callback, childrenName)
}
}
}

数据导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//data   二进制数据
//type 后缀 xlsx doc等
export const exportBUfferData = (data, type) => {
let binaryData = [];
binaryData.push(data);
let href = window.URL.createObjectURL(new Blob(
binaryData));
let link = document.createElement('a')
link.download = this.exportTitle + '.' + type
link.style.display = 'none'
link.href = href
// 触发点击
document.body.appendChild(link)
link.click()
// 移除
document.body.removeChild(link)
}

获取地址栏参数

1
2
3
4
5
6
export const GetQueryString = (name) => {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}

echarts图表自动hover轮播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
export const autoHover = (myChart, num = 10, time = 2000) => {
let count = 0
let timeTicket = null
timeTicket && clearInterval(timeTicket)
// clearAllInterval()
timeTicket = setInterval(function () {
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0 // serieIndex的索引值 可以触发多个
})
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: count
})
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: count
})
count++
if (count >= num) {
count = 0
}
}, time)
myChart.on('mouseover', function (params) {
// clearAllInterval()
clearInterval(timeTicket)
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0
})
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: params.dataIndex
})
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: params.dataIndex
})
})

myChart.on('mouseout', function () {
// clearAllInterval()
timeTicket && clearInterval(timeTicket)
timeTicket = setInterval(function () {
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0 // serieIndex的索引值 可以触发多个
})
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: count
})
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: count
})
count++
if (count >= num) {
count = 0
}
}, 3000)
})
return timeTicket

}

清除所有定时器

1
2
3
4
5
6
export const clearAllInterval = () => {
let s = setInterval(() => {}, 1)
for (let i = 0; i < s; i++) {
clearInterval(i)
}
}

时间转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
export const formatPast = (date, type = "default", zeroFillFlag = true) => {
// 定义countTime变量,用于存储计算后的数据
let countTime;
// 获取当前时间戳
let time = new Date().getTime();
// 转换传入参数为时间戳
let afferentTime = new Date(date).getTime();
// 当前时间戳 - 传入时间戳
time = Number.parseInt(`${time - afferentTime}`);
if (time < 10000) {
// 10秒内
return "刚刚";
} else if (time < 60000) {
// 超过10秒少于1分钟内
countTime = Math.floor(time / 1000);
return `${countTime}秒前`;
} else if (time < 3600000) {
// 超过1分钟少于1小时
countTime = Math.floor(time / 60000);
return `${countTime}分钟前`;
} else if (time < 86400000) {
// 超过1小时少于24小时
countTime = Math.floor(time / 3600000);
return `${countTime}小时前`;
} else if (time >= 86400000 && type == "default") {
// 超过二十四小时(一天)且格式参数为默认"default"
countTime = Math.floor(time / 86400000);
//大于等于365天
if (countTime >= 365) {
return `${Math.floor(countTime / 365)}年前`;
}
//大于等于30天
if (countTime >= 30) {
return `${Math.floor(countTime / 30)}个月前`;
}
return `${countTime}天前`;
} else {
// 一天(24小时)以上且格式不为"default"则按传入格式参数显示不同格式
// 数字补零
let Y = new Date(date).getFullYear();
let M = new Date(date).getMonth() + 1;
let zeroFillM = M > 9 ? M : "0" + M;
let D = new Date(date).getDate();
let zeroFillD = D > 9 ? D : "0" + D;
// 传入格式为"-" "/" "."
if (type == "-" || type == "/" || type == ".") {
return zeroFillFlag
? Y + type + zeroFillM + type + zeroFillD
: Y + type + M + type + D;
}
// 传入格式为"年月日"
if (type == "年月日") {
return zeroFillFlag
? Y + type[0] + zeroFillM + type[1] + zeroFillD + type[2]
: Y + type[0] + M + type[1] + D + type[2];
}
// 传入格式为"月日"
if (type == "月日") {
return zeroFillFlag
? zeroFillM + type[0] + zeroFillD + type[1]
: M + type[0] + D + type[1]
}
// 传入格式为"年"
if (type == "年") {
return Y + type
}

}
};
// console.log(formatPast("2024-1-1 11:11:11")); // 3天前
// console.log(formatPast("2023-11-1 11:11:11")); // 2个月前
// console.log(formatPast("2015-07-10 21:32:01")); // 8年前
// console.log(formatPast("2023-02-01 09:32:01", "-", false)); // 2023-2-1
// console.log(formatPast("2023.12.8 19:32:01", "/")); // 2023/12/08
// console.log(formatPast("2023.12.8 19:32:01", ".")); // 2023.12.08
// console.log(formatPast("2023/5/10 11:32:01", "年月日")); // 2023年05月10日
// console.log(formatPast("2023/6/25 11:32:01", "月日", false)); // 6月25日
// console.log(formatPast("2023/8/08 11:32:01", "年")); // 2023年

限于当时的水平所限,很多方法现在看来都有更好的写法,大家有更好的版本可以在评论区指教~