util文件汇总
1. 判断两个对象比较属性键的顺序是否一样
1 export function isObjectOrderSame(obj1: any, obj2: any) { 2 const keys1 = Object.keys(obj1); 3 const keys2 = Object.keys(obj2); 4 if (keys1.length !== keys2.length) { 5 return false; 6 } 7 return keys1.every((key, index) => key === keys2[index]); 8 }
2. 判断两个对象比较属性键和属性值的顺序是否一样
1 export function isObjectOrderSameAll(obj1: any, obj2: any) { 2 const entries1 = Object.entries(obj1); 3 const entries2 = Object.entries(obj2); 4 5 if (entries1.length !== entries2.length) return false; 6 7 return entries1.every(([key1, value1], index) => { 8 const [key2, value2] = entries2[index]; 9 return key1 === key2 && value1 === value2; 10 }); 11 }
3. 下载文件,自定义文件名称
1 export function downFile(url: any, fileName: any) { 2 const x = new XMLHttpRequest(); 3 x.open("GET", url, true); 4 x.responseType = "blob"; 5 x.onload = function () { 6 const url = window.URL.createObjectURL(x.response); 7 const a = document.createElement("a"); 8 a.href = url; 9 a.download = fileName; 10 a.click(); 11 }; 12 x.send(); 13 }
4. 判断是否是IE环境
1 export const isIE = () => { 2 const UA = window.navigator.userAgent || ''; // 检查 IE 浏览器 3 if ( 4 UA.indexOf('MSIE') !== -1 || 5 UA.indexOf('Trident/') !== -1 || 6 'ActiveXObject' in window 7 ) 8 return true; 9 return false; 10 };
5. react 封装配置权限
1 // permission.ts文件: 2 import { history } from 'umi'; 3 4 // 权限类型 5 export enum PERMISSION_TYPE { 6 ADD = 'add', // 新增 7 UPDATE = 'update', //编辑 8 SELECT = 'select', // 查询 9 DELETE = 'delete', //删除 10 SIGN_IN = 'signIn', //签收 11 EXAMINE = 'examine', //投稿审核 12 UPLOAD = 'upload', //上传图片 13 LOOK_OVER = 'lookOver', //查看记录 14 LEADING = 'leading', //批量导入 15 SIGN = 'sign', // 签收 16 } 17 type MenuItem = { 18 children: Array<MenuItem>; 19 routePath: string; 20 perms: PERMISSION_TYPE; 21 }; 22 const permissionCache: Map<string, boolean> = new Map<string, boolean>(); 23 /** 24 * 检查权限 25 * @param permission 权限类型 26 */ 27 export const checkPermission = (permission: PERMISSION_TYPE): boolean => { 28 let result = false; 29 try { 30 const cacheValue = permissionCache.get( 31 `${history.location.pathname}_${permission}`, 32 ); 33 if (cacheValue !== undefined) { 34 return cacheValue; 35 } 36 const munPowers = JSON.parse(localStorage.getItem('munPowers') || '[]'); 37 const functions = munPowers 38 .map((module: MenuItem) => module.children) 39 .reduce((a: Array<MenuItem>, b: Array<MenuItem>) => a.concat(b), []); 40 const targetFunc = functions.find( 41 (func: MenuItem) => func.routePath === history.location.pathname, 42 ); 43 result = !!( 44 targetFunc && 45 targetFunc.children.find(({ perms }: MenuItem) => perms == permission) 46 ); 47 permissionCache.set(`${history.location.pathname}_${permission}`, result); 48 } catch (e) { 49 result = false; 50 } 51 return result; 52 }; 53 54 a.tsx页面中使用方法: 55 import { checkPermission, PERMISSION_TYPE } from '@/utils/permission'; 56 57 {checkPermission(PERMISSION_TYPE.ADD) && (<Link className={styles.addButton} to={addUrl}>新增</Link>)}
6. 密码验证规则,支持 数字、大写字母、小写字母、特殊字符 中的至少三种。字符长度6-16位
1 export const passwordReg = /^(?![\dA-Z]+$)(?![\da-z]+$)(?![\d\W]+$)(?![a-zA-Z]+$)(?![a-z\W]+$)(?![A-Z\W]+$)[A-Za-z\W\d]{8,16}$/g;
7. 密码验证规则,支持 数字、大写字母、小写字母、特殊字符全部4种,并且至少两个特殊字符,长度6-16位
1 export const passwordReg = 2 /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\W].*[\W])[a-zA-Z0-9\W]{8,16}$/g;
8. 判断浏览器 移动端/pc端
1 export function isMobile() { 2 if ( 3 window.navigator.userAgent.match( 4 /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i, 5 ) 6 ) { 7 return true; // 移动端 8 } else { 9 return false; // PC端 10 } 11 }
9. 数组去重:
1. 使用 Set 数据结构:
1 const arr = [1, 2, 3, 4, 2, 3, 1, 5]; 2 const uniqueArr = [...new Set(arr)]; 3 4 console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
2. 使用 Array.filter() 方法:
1 const arr = [1, 2, 3, 4, 2, 3, 1, 5]; 2 const uniqueArr = arr.filter((value, index, self) => { 3 return self.indexOf(value) === index; 4 }); 5 console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
3. 使用 Array.reduce() 方法:
1 const arr = [1, 2, 3, 4, 2, 3, 1, 5]; 2 const uniqueArr = arr.reduce((acc: any, value: any) => { 3 if (!acc.includes(value)) { 4 acc.push(value); 5 } 6 return acc; 7 }, []); 8 console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
10. 数组中对象去重:
1. 使用 Set 数据结构,将对象转换为字符串进行去重,然后再转换回对象:
1 const arr = [ 2 { id: 1, name: 'John' }, 3 { id: 2, name: 'Jane' }, 4 { id: 1, name: 'John' }, 5 { id: 3, name: 'Alice' } 6 ]; 7 8 const uniqueArr = Array.from(new Set(arr.map(JSON.stringify))).map(JSON.parse); 9 console.log(uniqueArr); 10 // 输出: 11 // [ 12 // { id: 1, name: 'John' }, 13 // { id: 2, name: 'Jane' }, 14 // { id: 3, name: 'Alice' } 15 // ]
2. 使用 reduce() 方法,通过比较对象的字符串形式来判断是否已经存在于累加器中。:
1 const arr = [ 2 { id: 1, name: 'John' }, 3 { id: 2, name: 'Jane' }, 4 { id: 1, name: 'John' }, 5 { id: 3, name: 'Alice' } 6 ]; 7 8 const uniqueArr = arr.reduce((acc, obj) => { 9 const found = acc.find(item => JSON.stringify(item) === JSON.stringify(obj)); 10 if (!found) { 11 acc.push(obj); 12 } 13 return acc; 14 }, []); 15 console.log(uniqueArr); 16 // 输出: 17 // [ 18 // { id: 1, name: 'John' }, 19 // { id: 2, name: 'Jane' }, 20 // { id: 3, name: 'Alice' } 21 // ]
3. Map方法
set方法设置key所对应的键值,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
values方法可以返回Map对象值的遍历器对象
1 let arr = [{ 2 id: '1', 3 key: '1', 4 value: '张三' 5 }, { 6 id: '3', 7 key: '2', 8 value: '小明' 9 }, { 10 id: '2', 11 key: '3', 12 value: '小红' 13 }, { 14 id: '1', 15 key: '1', 16 value: '王五' 17 }, { 18 id: '1', 19 key: '2', 20 value: '小美' 21 }] 22 let map = new Map(); 23 for (let item of this.arr) { 24 map.set(item.id, item); 25 } 26 this.arr = [...map.values()]; 27 console.log(this.arr)
4. reduce() 方法
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
1 const obj = {} 2 arr = arr.reduce((total, next) => { 3 obj[next.key] ? '' : obj[next.key] = true && total.push(next) 4 return total 5 }, []) 6 console.log(arr)
这里还有一个需求,如果有两个或者多个判断条件,给数组对象去重,加一个判断条件就行了
1 const hasObj = {} 2 arr = arr.reduce((total, next) => { 3 const filterKey = next.key + next.id; 4 hasObj[filterKey] ? "" : hasObj[filterKey] = true && total.push(next) 5 return total 6 }, []) 7 console.log(arr)
11. 数组排序:
1. 默认排序:
1 const arr = [3, 1, 4, 2, 5];2 arr.sort((a, b) => a - b);3 console.log(arr); // 输出 [1, 2, 3, 4, 5]
2. 数组中对象根据某个值进行顺序排序:
1 const arr = [ 2 { id: 3, name: "John" }, 3 { id: 1, name: "Alice" }, 4 { id: 2, name: "Bob" }, 5 { id: 0, name: "Cob" }, 6 ]; 7 arr.sort((a, b) => a.id - b.id); 8 console.log(arr);
3. 根据自定义数组顺序进行排序:
1 const list = [ 2 { age:12, name:"小明" }, 3 { age:8, name:"小张" }, 4 { age:16, name:"小美" }, 5 { age:20, name:"小李" } 6 ] 7 const order = [ "小美", "小明", "小李", "小张" ] 8 const arr = list.sort((a:any, b:any) => { 9 return order.indexOf(a.name) - order.indexOf(b.name) 10 }) 11 12 console.log(arr); 13 // 输出: 14 // [ 15 // { age:16, name:"小美" }, 16 // { age:12, name:"小明" }, 17 // { age:20 name:"小李" }, 18 // { age:8, name:"小张" } 19 // ]
12. 正则校验身份证号:
1 export const validateIDCard = (idCard)=> { 2 const pattern = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/; 3 return pattern.test(idCard); 4 }
13. 正则校验手机号:
1 export const validatePhoneNumber = (phoneNumber)=> { 2 const pattern = /^1[3456789]\d{9}$/; 3 4 return pattern.test(phoneNumber); 5 }
14. 通过出生日期获取周岁年龄
1 export const getAgeFromBirthYearMonth = (strBirthday) => { 2 var returnAge, 3 strBirthdayArr = strBirthday.split("-"), 4 birthYear = strBirthdayArr[0], 5 birthMonth = strBirthdayArr[1], 6 birthDay = strBirthdayArr[2], 7 d = new Date(), 8 nowYear = d.getFullYear(), 9 nowMonth = d.getMonth() + 1, 10 nowDay = d.getDate(); 11 if (nowYear == birthYear) { 12 returnAge = 0;//同年 则为0周岁 13 } 14 else { 15 var ageDiff = nowYear - birthYear; //年之差 16 if (ageDiff > 0) { 17 if (nowMonth == birthMonth) { 18 var dayDiff = nowDay - birthDay;//日之差 19 if (dayDiff < 0) { 20 returnAge = ageDiff - 1; 21 } else { 22 returnAge = ageDiff; 23 } 24 } else { 25 var monthDiff = nowMonth - birthMonth;//月之差 26 if (monthDiff < 0) { 27 returnAge = ageDiff - 1; 28 } 29 else { 30 returnAge = ageDiff; 31 } 32 } 33 } else { 34 returnAge = -1;//返回-1 表示出生日期输入错误 晚于今天 35 } 36 } 37 return returnAge;//返回周岁年龄 38 }
15. 数字转中文数字:
1 export function changeNumToHan (num) { 2 var arr1 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] 3 var arr2 = ['', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '万', '十', '百', '千', '亿'] 4 if (!num || isNaN(num)) return '零' 5 var english = num.toString().split('') 6 var result = '' 7 for (var i = 0; i < english.length; i++) { 8 var des_i = english.length - 1 - i// 倒序排列设值 9 result = arr2[i] + result 10 var arr1_index = english[des_i] 11 result = arr1[arr1_index] + result 12 } 13 result = result.replace(/零(千|百|十)/g, '零').replace(/十零/g, '十') // 将【零千、零百】换成【零】 【十零】换成【十】 14 result = result.replace(/零+/g, '零') // 合并中间多个零为一个零 15 result = result.replace(/零亿/g, '亿').replace(/零万/g, '万') // 将【零亿】换成【亿】【零万】换成【万】 16 result = result.replace(/亿万/g, '亿') // 将【亿万】换成【亿】 17 result = result.replace(/零+$/, '') // 移除末尾的零 18 // 将【一十】换成【十】 19 result = result.replace(/^一十/g, '十') 20 return result 21 }
16. 解析url参数:
1 function GetUrlParam(urlStr) { 2 // ?a=1&b=2&c=3 ==> {a: "1", b: "2", c: "3"} 3 let url = urlStr.toString(); 4 let arrObj = url.split("?"); // split字符串分割成字符串数组,按照?分割 5 let params = Object.create(null); 6 if (arrObj.length > 1) { 7 arrObj = arrObj[1].split("&"); 8 arrObj.forEach((item) => { 9 item = item.split("="); 10 params[item[0]] = item[1]; 11 }); 12 } 13 return params; 14 } 15 console.log( 16 GetUrlParam("http://192.168.1.12:9528/#/report?Id=359&name=ABC") 17 ); 18 // 解析结果:{Id: '359', name: 'ABC'}
17. 指定范围的随意数
1 function RandomNum(min, max) { 2 return Math.floor(Math.random() * (max - min + 1)) + min; 3 }
18. 生成随机字符串
1 function randomSting(str){ 2 Math.random.toString(36).slice(2) 3 } 4 5 randomSting()