总结这一年在项目中用到频率较多的工具函数
概述
每个项目必然会用到各种各样的工具函数处理不同的逻辑,我自己总结了我这一年多开发以来,用到的比较普遍的一些工具函数,我个人不太喜欢用loadash,不如自己用到的时候自己封装。
关于表单验证的
以下总结的为组件库中Form组件对应的自定义校验规则函数,本质上也用到了校验工具async-validator,更多的细节,可以去文档看,对于做后台系统的,涉及到大量的表单,表单验证必不可少。
验证手机号
function CheckPhone (rule, value, callback) {
let reg = /^1\d{10}$/g;
if (!reg.test(value)) {
callback(new Error('手机号格式不正确'));
} else {
callback();
}
}
验证密码
function CheckAdminPassword (rule, value, callback) {
const reg = /[\u4e00-\u9fa5]|\s+/gm;
const len = value.length;
if (value) {
if (len < 8 || len > 14) {
callback(new Error('密码必须由字母/数字及标点符号3种组成,且字母需大小写都包含,不得有空格、中文,长度8-14位'));
}
if (reg.test(value)) {
callback(new Error('密码必须由字母/数字及标点符号3种组成,且字母需大小写都包含,不得有空格、中文,长度8-14位'));
}
if (!checkPwdCombination(value, 'admin')) {
callback(new Error('密码须由字母/数字及标点符号3种组成,且字母需大小写都包含,不得有空格、中文,长度8-14位'));
}
}
callback();
}
验证正整数(包含0)
function CheckPositiveInteger (rule, value, callback){
let reg = /^[1-9]\d*$/g;
// console.log(value)
if (!reg.test(value) && value !== '') {
callback(new Error('请输入正整数'));
} else {
callback();
}
}
验证邮箱
function CheckEmail (rule, value, callback){
let reg = /^[A-z0-9_]{3,12}@[A-z0-9]{2,12}(\.com|\.cn|\.com\.cn)$/g;
if (!reg.test(value) && value !== '') {
callback('邮箱格式不正确');
} else {
callback();
}
}
验证价格
function CheckPrice (rule, value, callback) {
if (!value && value !== 0) {
return callback(new Error('该项为必填项'));
} else if (!parseFloat(value) && parseFloat(value) != 0) {
return callback(new Error('请输入阿拉伯数字'));
} else if (value < 0) {
return callback(new Error('请输入正确的价格'));
} else {
callback();
}
}
验证年龄
function CheckAge (rule, value, callback) {
let reg = /\D/g;
if (reg.test(value)) {
callback(new Error('年龄只能为正整数'));
} else if (parseInt(value) >= 120 || parseInt(value) < 0) {
callback(new Error('年龄只能小于120'));
} else {
callback();
}
}
验证IP地址
function CheckIp (rule, value, callback) {
let reg =
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
if (!reg.test(value) && value !== '') {
callback(new Error('输入正确IP地址'));
} else {
callback();
}
}
验证域名网址
function CheckWebsite (rule, value, callback) {
let reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
if (!reg.test(value) && value !== '') {
callback(new Error('请输入正确的网址'));
} else {
callback();
}
}
关于功能类的工具函数
主要用于数据转化,性能提升而用的
判断当前是电脑端还是移动端
const checkCurrentDeviceType = function () {
let ua = navigator.userAgent.toLowerCase();
let btypeInfo = (ua.match(/firefox|chrome|safari|opera/g) || 'other')[0];
if ((ua.match(/msie|trident/g) || [])[0]) {
btypeInfo = 'msie';
}
let pc = '';
let prefix = '';
let plat = '';
//如果没有触摸事件 判定为PC
let isTocuh = 'ontouchstart' in window || ua.indexOf('touch') !== -1 || ua.indexOf('mobile') !== -1;
if (isTocuh) {
if (ua.indexOf('ipad') !== -1) {
pc = 'pad';
} else if (ua.indexOf('mobile') !== -1) {
pc = 'mobile';
} else if (ua.indexOf('android') !== -1) {
pc = 'androidPad';
} else {
pc = 'pc';
}
} else {
pc = 'pc';
}
switch (btypeInfo) {
case 'chrome':
case 'safari':
case 'mobile':
prefix = 'webkit';
break;
case 'msie':
prefix = 'ms';
break;
case 'firefox':
prefix = 'Moz';
break;
case 'opera':
prefix = 'O';
break;
default:
prefix = 'webkit';
break;
}
plat = ua.indexOf('android') > 0 ? 'android' : navigator.platform.toLowerCase();
return {
version: (ua.match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1], //版本
plat: plat, //系统
type: btypeInfo, //浏览器
pc: pc,
prefix: prefix, //前缀
isMobile: pc == 'pc' ? false : true, //是否是移动端
};
};
根据链接地址下载文件
const dowloadFile = function (url) {
let a = document.createElement('a');
a.href = url;
a.click();
};
判断起止时间一定要比结束时间小
const isValidTime = function (startTime, endTime) {
return new Date(endTime).getTime() > new Date(startTime).getTime();
};
树形结构数据转化(侧边栏或者权限管理)
/**
* @Description 组合接口返回的侧边栏路由为树形结构
* @param { Array } data 需要处理的数据
* @return { Array } 组合完成的树形结构
**/
/**
转化规则如下:
const data = [
{
parent: 0,
label: '菜单1',
id: 1,
},
{
parent: 0,
label: '菜单2',
id: 2,
},
{
parent: 0,
label: '菜单3',
id: 3,
},
{
parent: 2,
label: '菜单2-1',
id: 4,
},
{
parent: 3,
label: '菜单3-1',
id: 5,
},
{
parent: 5,
label: '菜单3-1-1',
id: 6,
},
]; ===>
data = [
{
parent: 0,
label: '菜单1',
id: 1,
},
{
parent: 0,
label: '菜单2',
id: 2,
children:[
{
parent: 2,
label: '菜单2-1',
id: 4,
},
]
},
{
parent: 0,
label: '菜单3',
id: 3,
children:[
{
parent: 3,
label: '菜单3-1',
id: 5,
children:[
{
parent: 5,
label: '菜单3-1-1',
id: 6,
},
]
},
]
},
];
**/
const getSideMenuListToTree = function (data) {
data ? (data = data) : (data = []);
let parent = data.filter(item => item.ParentId == 0); //一级菜单
let childrens = data.filter(item => item.ParentId != 0); //子级菜单
function formatToTree(parent, childrens) {
parent.forEach(x => {
childrens.forEach(v => {
if (x.Id == v.ParentId) {
x.children ? x.children.push(v) : (x.children = [v]);
formatToTree(x.children, childrens);
}
});
});
}
function solveTreeData(parent, list) {
parent.forEach(item => {
list.push({
label: item.Title,
path: item.Url,
children: (item.children && item.children.length && solveTreeData(item.children, [])) || [],
});
});
return list;
}
formatToTree(parent, childrens);
let res = solveTreeData(parent, []);
return res;
};
手机号脱敏显示
/**
*@Author:
*@Description: 手机号脱敏处理
* @param { String } 手机号 155xxxxx447
* @return { String } 返回脱敏处理的手机号 155***447
*/
const phoneDesensitizationTreatment = (phone) {
return phone.replace(/(\d{3})(\d{4})(\d{4})/, (str, $1, $2, $3) => {
return $1 + '****' + $3;
});
};
节流函数
/**
*@Author:
*@Description: 节流函数
* @param { Function } fn 需要节流函数
* @param { Number } wait 间隔时间差
* @param { Function } callback 此回调函数用于获取函数返回值
*/
const throw = function (fn, wait, callback) {
let initTime = 0;
return function () {
let nowTime = Date.now();
if ((nowTime = initTime >= wait)) {
let res = fn.apply(this, [...arguments]);
if (typeof callback == 'function') callback(res);
initTime = nowTime;
}
};
};
防抖函数
/**
*@Description: 防抖函数(简化版,项目需求够用了,也不是写啥子库,业务简单防抖就行,不需要花里胡哨的)
* @param { Function } fn 需要防抖的函数
* @param { Number } wait 间隔时间差
* @param { Boolean } immediate 是否开始立即执行
* @param { Function } callback 此回调函数用于获取函数返回值
*/
const debounce = function (fn, wait, immediate = false, callback) {
let timer = null;
let ivoke = false;
return function () {
if (timer) clearTimeout(timer);
if (immediate && !ivoke) {
let res = fn.apply(this, [...arguments]);
if (typeof callback == 'function') callback(res);
ivoke = true;
} else {
timer = setTimeout(() => {
let res = fn.apply(this, [...arguments]);
if (typeof callback == 'function') callback(res);
ivoke = true;
}, wait);
}
};
};
是生成浏览器设备标识
需要借助指纹库:Fingerprint2
//根据当前浏览器生成一个字符串标识当前主机
const getBrowerDeviceIdentificationId = async function () {
return new Promise(async (resolve, reject) => {
const fp = await Fingerprint2.load();
const result = await fp.get();
const visitorId = result.visitorId;
resolve(visitorId);
});
};
删除对象中的空值(根据需要可递归)
// 删除对象中的空字段
const deleteKey = function o(bj) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const element = obj[key];
if (element !== 0 && !element && typeof element !== 'boolean') {
delete obj[key];
}
}
}
return obj;
};
时间转化
需要借助时间转化插件:moment.js
const transformDate = function (val, type) {
switch (type) {
case 1:
return moment(val).format('YYYY/MM/DD');
case 2:
return moment(val).format('YYYY-M-D');
case 3:
return moment(val).format('YYYY年M月');
case 4:
return moment(val).format('YYYY-MM-DD HH:mm');
case 5:
return moment(val).format('YYYY-MM-DD');
case 6:
return moment(val).format('YYYY年MM月DD日');
case 7:
return moment(val).fromNow(); //几天前/几年前/几秒前的格式
case 8:
return moment(val).format('YYYY/MM/DD HH:mm');
case 9:
return Math.floor((moment(val) - moment()) / 3600000); //时间相减剩余小时(主要用于设置过期时间)
}
};
总结
后面会不断追加在项目中常用的一些工具函数,这里记录下,不然每次从头写还是很麻烦的
转载自:https://juejin.cn/post/7160594615723098126