大家好,我是鹿萌萌,总结一下在我工作中用过的非常实用的一些工具函数
喜欢萌萌的欢迎一键三连💗💗💗
判断是否为空
export const isEmpty = target => {
// '' null undefined 0
if (!target) {
return true;
}
// 空数组
if (Array.prototype.isPrototypeOf(target) && target.length === 0) {
return true;
}
// 空对象
if ((Object.prototype.isPrototypeOf(target)) && (Object.keys(target).length === 0)) {
return true;
}
return false;
};
时间戳转为日期
export function timestampToTime(timestamp) {
const date = new Date(timestamp * 1000);// 时间戳为10位需*1000,时间戳为13位的话不需乘1000
const Y = date.getFullYear() + '-';
const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
const h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
const m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
const s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
return Y + M + D + h + m + s;
}
将a=1&b=2 这种querystring转为object
export const querystringToObj = (string) => {
const obj = {};
string.split('&').forEach(item => {
const [key, value] = item.split('=');
obj[key] = value;
});
return obj;
};
获取url某个参数的值
export const getUrlParam = name => {
let reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
let r = window.location.search.substr(1).match(reg);
if (r !== null) {
return r[2];
}
return '';
};
使用:const param = getUrlParam('param') || ''
获取base64
export const getBase64 = (file: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
};
字符串截取拼接...
export const formatName = (value, num) => {
if (!value) {
return '';
}
if (value.length > num) {
let strArr = Array.from(String(value));
value = strArr.slice(0, num).join('') + '...';
return value;
}
return value;
};
多个参数拼接起来
// object 转 str for url
export const buildParam = data => {
if (typeof data === 'object') {
return Object.keys(data)
.map(key => {
let value = data[key] === undefined ? '' : encodeURIComponent(data[key]);
return `${key}=${value}`;
})
.join('&');
}
return '';
};
// 使用
const options = {
param: 'param'
};
const protocol = window.location.protocol || 'https:';
const path = `${protocol}//www.baidu.com`;
const url = `${path}/index.html?${buildParam(options)}`;
数据处理
export function toFixed(num: number) {
// toFixed原生函数会四舍五入
const [n1, n2] = `${num}`.split('.');
return `${n1}${n2 ? `.${n2.slice(0, 1)}` : '.0'}`;
}
export function formatVal(number?: string | number) {
const num = number ? +number : 0;
if (num > 99999999) {
return toFixed(num / 100000000) + '亿';
}
if (num > 9999999) {
return toFixed(num / 10000000) + 'kw';
}
if (num > 9999) {
return toFixed(num / 10000) + 'w';
}
return num;
}
// 保留2位小数(不够位数,则用0替补)
export function keepTwoDecimalFull(num: number) {
let result = parseFloat(String(num));
if (isNaN(result)) {
return false;
}
result = Math.round(num * 100) / 100;
let s_x = result.toString(); // 将数字转换为字符串
let pos_decimal = s_x.toString().indexOf('.'); // 小数点的索引值
// 当整数时,pos_decimal=-1 自动补0
if (pos_decimal < 0) {
pos_decimal = s_x.length;
s_x += '.';
}
// 当数字的长度< 小数点索引+2时,补0
while (s_x.length <= pos_decimal + 2) {
s_x += '0';
}
return s_x;
}
/**
* @method 数字金额中间加上逗号
* @param {number | string} index
* @returns string
*/
export const moneyFormat = item => {
let num = (item || 0).toString();
let result = '';
while (num.length > 3) {
result = `,${num.slice(-3)}${result}`;
num = num.slice(0, num.length - 3);
}
if (num) {
result = num + result;
}
return result;
};
时间格式处理
const formatTime = (z: number, type = 1) => {
let time = new Date(z * 1000);
let Month = String(time.getMonth() + 1);
let Day = String(time.getDate());
let Hour = String(time.getHours());
let Minute = String(time.getMinutes());
if (String(Month).length === 1) {
Month = '0' + Month;
}
if (String(Day).length === 1) {
Day = '0' + Day;
}
if (String(Hour).length === 1) {
Hour = '0' + Hour;
}
if (String(Minute).length === 1) {
Minute = '0' + Minute;
}
let timeValue = null;
if (type === 0) {
return [Month, Day, Hour, Minute];
}
switch (type) {
case 0:
timeValue = [Month, Day, Hour, Minute];
break;
case 1:
timeValue = `${Month}月${Day}日${Hour}:${Minute}`;
break;
case 2:
timeValue = `${Hour}:${Minute}`;
break;
case 3:
timeValue = `${Month}月${Day}日 ${Hour}:${Minute}`;
break;
case 4:
timeValue = `${Month}月${Day}日 ${Hour}:${Minute}`;
break;
default:
break;
}
return timeValue;
};
export const showInfoLiveTime = (live_start_time: number, live_end_time: number) => {
let start = formatTime(live_start_time, 4);
let end = formatTime(live_end_time, 4);
return `${start} - ${end}`;
};
storag get/set
/**
* @param key 要获取的localStorage key
* @returns {*} parse过的storage值
*/
export function getStorage(key) {
let res = window.localStorage.getItem(key);
try {
res = JSON.parse(res);
} catch (e) {
// 返回值非json字符串,不处理,直接返回
}
return res;
}
/**
* @param key 要添加/更新的localStorage key
* @param value 要添加/更新的localStorage 值
*/
export function setStorage(key, value) {
let parsedValue = value;
if (typeof value !== 'string') {
parsedValue = JSON.stringify(value);
}
window.localStorage.setItem(key, parsedValue);
}
星星展示
/**
* 星级转换 例如4.5转换成[1, 1, 1, 1, 0.5, 0],用于渲染星级icon
* @params {Number} 星级分数
* @return {Array} 星级数组长度
*/
export const handleStar = (numParam, len = 5) => {
const num = Number(numParam);
if (typeof num !== 'number') {
return [];
}
const lower = Math.floor(num);
let arr = Array.from({length: len}, (v, idx) => {
if (idx < lower) {
return 1;
}
if (numParam - idx > 0) {
// 有小数
return numParam - idx;
}
return 0;
});
return arr;
};
import React from 'react';
import './index.less';
import {handleStar} from '@/utils/utils';
/**
* 星级评分
* @params {Number} number 星级得分
* @params {Number} full 总分(共需要展示几个星星)默认五颗星
* @params {String} baseColor 星星默认色值(没有得分时色值) 默认#E0E0E0
* @params {String} fullColor 得分高亮的色值 默认#FF3333
* @params {String} fontSize 控制星星宽度 默认20px
* @params {String} lineHeight 星星高度 默认20px
* @params {String} margin 星星间距 默认10px
* @params {Number} step 默认按照0.5处理小数部分星星展示
* @return {Null}
*/
export default function Star(props) {
let {
number = 0,
fontSize = '20px',
lineHeight = '20px',
margin = '10px',
full = 5,
baseColor = '#E0E0E0',
fullColor = '#FF3333',
step
} = props;
if (step) {
let remainder = number % 1;
if (remainder && remainder > 0.5) {
number = Math.floor(number) + 1;
}
else if (remainder && remainder < 0.5) {
number = Math.floor(number) + 0.5;
}
}
let defaultStar = {
color: baseColor,
lineHeight: lineHeight,
fontSize: fontSize,
marginRight: margin
};
let fullStarFun = value => {
return {
color: fullColor,
width: value
};
};
let clickItemStar = idx => {
props.clickItemStar && props.clickItemStar(idx + 1);
};
return (
<div className="innerstar-wrapper">
{handleStar(number, full).map((item, idx) => (
// eslint-disable-next-line react/no-array-index-key
<span className="org_star" style={defaultStar} key={idx} onClick={() => clickItemStar(idx)}>
{item !== 0 && (
<span className="full-star" style={fullStarFun(item * 100 + '%')}>

</span>
)}

</span>
))}
</div>
);
}
<div className='title-star'>
<Star
step={0.5}
number={item.star}
fullColor='#FFBF00'
fontSize='12px'
lineHeight='15px'
margin='2px'
/>
{+item.star !== 0 && <span className='avg'>{item.star.toFixed(1)}</span>}
</div>
平滑滚动
/**
* @param {*} element 滚动的元素 默认window
* @param {*} scrollTo 要滚动到的距离
* @return {*}
*/
const scrollSmooth = (scrollTo) => {
if (isIOS) {
const stepLength = 25;
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let distance = scrollTo - scrollTop;
const step = () => {
if (distance > 0) {
scrollTop = scrollTop + stepLength > scrollTo ? scrollTo : scrollTop + stepLength;
}
if (distance < 0) {
scrollTop = scrollTop - stepLength > scrollTo ? scrollTop - stepLength : scrollTo;
}
if (scrollTop === scrollTo) {
window.scrollTo(0, scrollTop);
}
else {
window.scrollTo(0, scrollTop);
requestAnimationFrame(step);
}
};
step();
}
else {
// 安卓手百轻框架这样执行会卡顿,用原生方法实现
window.scrollTo({
top: scrollTo,
behavior: 'smooth'
});
}
};
export {scrollSmooth};
axios请求
import axios from 'axios';
import qs from 'qs';
// 声明一个数组用于存储每个ajax请求的取消函数和ajax标识,只针对get请求取消
let pending = [];
let cancelToken = axios.CancelToken;
let removePending = config => {
for (let item in pending) {
// 当前请求在数组中存在时执行函数体
if (pending[item].url === config.url) {
// 执行取消操作
pending[item].cancelFn();
// 把这条记录从数组中移除
pending.splice(item, 1);
}
}
};
const axiosInstance = axios.create();
axiosInstance.defaults.withCredentials = true;
// 添加请求拦截器
axiosInstance.interceptors.request.use(config => {
if (config.abort) {
removePending(config);
}
config.cancelToken = new cancelToken(token => {
pending.push({
cancelFn: token,
url: config.url
});
});
return config;
},
error => Promise.reject(error)
);
export const request = ({
params,
method = 'get',
url,
extParams = {},
// 网络异常返回空对象还是错误信息
errorReturnObject = false
}) => {
if (method.toLowerCase() === 'post') {
return axiosInstance.post(url, qs.stringify({
...params
})).then(res => res.data).catch((e) => {
return errorReturnObject ? {} : Promise.reject(e);
});
}
extParams = Object.assign(
{
abort: 1
},
extParams
);
// 用promise包一下,不然重复请求取消时也会走到catch里
return new Promise((resolve, reject) => {
axiosInstance.get(url, {
params: {
...params
},
...extParams
}).then(res => resolve(res.data)).catch((e) => {
if (e && e.__CANCEL__) {
console.warn('request 取消');
return;
}
return errorReturnObject ? {} : reject(e);
});
});
};
export default request;
// 使用:post
/**
* 返回一个对象字典排序后的字符串
* @param {Object} data
* @return {String} 字典排序后的字符串
*/
export const dictionaryOrder = (data) => {
let str = '';
const allkeys = Object.keys(data).sort();
for (let i = 0, len = allkeys.length; i < len; i++) {
str += `${allkeys[i]}=${data[allkeys[i]]}`;
}
return str;
};
export const getList = (options = {}) => {
const params = {
ts: +new Date(),
...options
};
params.sign = md5(dictionaryOrder(params) + token); // 是否需要md5加密
return request({
params,
url: `${HOST}/xxx/list`,
method: 'post'
});
};
// get
export const getList = (params = {}) => {
const options = {
...params
};
const url = 'xxxx';
return $get(url, options);
};
h5监听页面 visibilty 发生变化
export const onPageVisible = (callback) => {
onVisibleEvent(() => {
// 页面切换到前台
if (callback) {
callback();
}
else {
window.location.reload();
}
}, () => {
// 页面切换到后台
});
};
数字单位转化(处理成万、亿)
export const formatNumData = num => {
num = num || 0;
let o = {
num: num,
unit: '',
};
// 1w 以下
if (num < 10000) {
return o.num;
}
// 1w以上 1亿以下
if (num >= 10000 && num < 10000 * 10000) {
let n = Math.floor((num / 10000) * 10) / 10;
o.unit = '万';
o.num = n;
return o.num + o.unit;
}
// 1亿以上
let n = Math.floor((num / (10000 * 10000)) * 10) / 10;
o.unit = '亿';
o.num = n;
return o.num + o.unit;
};
// 处理过万展示
export const overFiveNumber = account => {
return account > 1e4 ? (account / 1e4).toFixed(1) + '万' : account;
};
随机长字符串
export const randomString = length => {
let chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
for (let i = length; i > 0; --i) {
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
};
日期格式化
/**
* 日期格式化
* @function dateFormat
* @param {Date} d - date 对象
* @param {string} [pattern = 'yyyy-MM-dd'] - 字符串
* @return {string} 处理后的字符串
* @example
* var d = new Date();
* dateFormat(d," yyyy年M月d日\n yyyy-MM-dd\n MM-dd-yy\n yyyy-MM-dd hh:mm:ss")
* //2018年11月10日\n 2018-01-01\n 01-01-18\n 2018-11-12 12:01:02
*/
export const dateFormat = (d, pattern = 'yyyy-MM-dd') => {
let y = d.getFullYear().toString();
let o = {
M: d.getMonth() + 1, // month
d: d.getDate(), // day
h: d.getHours(), // hour
m: d.getMinutes(), // minute
s: d.getSeconds(), // second
};
pattern = pattern.replace(/(y+)/gi, (a, b) => y.substr(4 - Math.min(4, b.length)));
Object.keys(o).forEach(i => {
pattern = pattern.replace(new RegExp('(' + i + '+)', 'g'), (a, b) => {
return o[i] < 10 && b.length > 1 ? '0' + o[i] : o[i];
});
});
return pattern;
};
运行环境的手机环境
const ua = navigator.userAgent.toLocaleLowerCase();
const browserList = {
toutiao: /TTWebView\/([\d\.]+)/i,
wechat: /MicroMessenger\/([\d\.]+)/i,
ipadqq: /IPadQQ\/([\d\.]+)/i,
mqq: /qq\/([\d\.]+)/i,
qzone: /QZONEJSSDK\/([\d\.]+)/i,
mqqbrowser: /mqqbrowser\/([\d\.]+)/i,
qqbrowser: /[^m]QQBrowser\/([\d\.]+)/i,
x5: /tbs\/(\d+)/i,
uc: /UCBrowser\/([\d\.]+)/i,
safari1: /Version\/(([\d\.]+))\sSafari\/[\d\.]+/i,
safari2: /Safari\/([\d\.]+)/i,
firefox: /Firefox\/([\d\.]+)/i,
opera: /OPR\/([\d\.]+)/i,
ie1: /MSIE\s([\d\.]+)/i,
ie2: /(trident\/\d\.\d)/i,
ie3: /(Edge)\/\d+\.\d+/i,
weibo: /weibo__([\d\.]+)/i,
qqnewsAd: /TADChid\/([\d\.]+)/i,
qqnews: /qqnews\/([\d\.]+)/i,
qqlive1: /QQLiveBrowser\/([\d\.]+)/i,
qqlive2: /QQLiveHDBrowser\/([\d\.]+)/i,
kuaibao: /qnreading\/([\d\.]+)/i,
liebao: /LieBaoFast\/([\d\.]+)/i,
douban: /com\.douban\.frodo\/([\d\.]+)/i,
miuibrowser: /MiuiBrowser/i,
baidulite: /lite baiduboxapp/i,
baidupro: /pro baidubox/i,
baiduinfo: /info baidubox/i,
baidu: /baiduboxapp/i,
baidukankan: /baiduboxvision/i,
browser360: /360browser/i,
oppobrowser: /OppoBrowser/i,
chrome1: /CriOS\/([\d\.]+)/i,
chrome2: /Chrome\/([\d\.]+)/i,
qqdownloader: /qqdownloader\/([\d\.]+)/i,
nintendo: /NintendoBrowser\/([\d\.]+)/i,
};
export const getBrwoserType = (ua = navigator.userAgent) => {
for (let i in browserList) {
if (ua.match(browserList[i])) {
return i;
}
}
return 'unknown';
};
export const isMobile = (ua = navigator.userAgent) => !!ua.match(/AppleWebKit.*Mobile.*/);
export const isPC = () => !window.navigator.userAgent.match(/Android|iPhone|SymbianOS|Windows Phone|iPad|Pod/);
获取手机品牌
export const getBrand = () => {
let brand = '';
/* eslint-disable */
let phone = [/IPHONE/gi, /huawei/gi, /mi/gi, /vivo/gi, /OPPO/gi, /samsung/gi, /SONY/gi, /Nokia/gi, /HTC/gi, /ZTE/gi, /Lenovo/gi, /ZUK/gi];
/* eslint-disable */
if (phone[0].test(ua)) {
brand = 'iPhone';
} else if (phone[1].test(ua)) {
brand = 'HUAWEI';
} else if (phone[2].test(ua)) {
brand = '小米';
} else if (phone[3].test(ua)) {
brand = 'vivo';
} else if (phone[4].test(ua)) {
brand = 'OPPO';
} else if (phone[5].test(ua)) {
brand = 'SAMSUNG';
} else if (phone[6].test(ua)) {
brand = 'SONY';
} else if (phone[7].test(ua)) {
brand = 'Nokia';
} else if (phone[8].test(ua)) {
brand = 'HTC';
} else if (phone[9].test(ua)) {
brand = 'ZTE';
} else if (phone[10].test(ua) || phone[11].test(ua)) {
brand = 'Lenovo';
} else {
brand = 'Android';
}
return brand;
};