![](https://img2022.cnblogs.com/blog/1161361/202209/1161361-20220908162016078-135762343.png)
前言
日常开发中,面对各种不同的需求,我们经常会用到以前开发过的一些工具函数,把这些工具函数收集起来,将大大提高我们的开发效率。
1、校验数据类型
| export const typeOf = function(obj) { |
| return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase() |
| } |
| |
示例:
| typeOf('树哥') |
| typeOf([]) |
| typeOf(new Date()) |
| typeOf(null) |
| typeOf(true) |
| typeOf(() => { }) |
| |
2、防抖
| export const debounce = (() => { |
| let timer = null |
| return (callback, wait = 800) => { |
| timer&&clearTimeout(timer) |
| timer = setTimeout(callback, wait) |
| } |
| })() |
示例:
如 vue 中使用
| methods: { |
| loadList() { |
| debounce(() => { |
| console.log('加载数据') |
| }, 500) |
| } |
| } |
3、节流
| export const throttle = (() => { |
| let last = 0 |
| return (callback, wait = 800) => { |
| let now = +new Date() |
| if (now - last > wait) { |
| callback() |
| last = now |
| } |
| } |
| })() |
4、手机号脱敏
| export const hideMobile = (mobile) => { |
| return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2") |
| } |
5、开启全屏
| 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() |
| } |
| } |
6、关闭全屏
| 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() |
| } |
| } |
7、大小写转换
参数:
- 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.substring(1).toLowerCase() |
| default: |
| return str |
| } |
| } |
示例:
| turnCase('vue', 1) |
| turnCase('REACT', 2) |
| turnCase('vue', 3) |
8、解析URL参数
| export const getSearchParams = () => { |
| const searchPar = new URLSearchParams(window.location.search) |
| const paramsObj = {} |
| for (const [key, value] of searchPar.entries()) { |
| paramsObj[key] = value |
| } |
| return paramsObj |
| } |
示例:
| // 假设目前位于 https://****com/index?id=154513&age=18; |
| getSearchParams(); // {id: "154513", age: "18"} |
9、判断手机是Andoird还是IOS
| |
| |
| |
| |
| |
| 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; |
| } |
10、数组对象根据字段去重
参数:
| 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 |
| } |
示例:
| const responseList = [ |
| { id: 1, name: '树哥' }, |
| { id: 2, name: '黄老爷' }, |
| { id: 3, name: '张麻子' }, |
| { id: 1, name: '黄老爷' }, |
| { id: 2, name: '张麻子' }, |
| { id: 3, name: '树哥' }, |
| { id: 1, name: '树哥' }, |
| { id: 2, name: '黄老爷' }, |
| { id: 3, name: '张麻子' }, |
| ] |
| |
| uniqueArrayObject(responseList, 'id') |
| // [{ id: 1, name: '树哥' },{ id: 2, name: '黄老爷' },{ id: 3, name: '张麻子' }] |
11、滚动到页面顶部
| export const scrollToTop = () => { |
| const height = document.documentElement.scrollTop || document.body.scrollTop; |
| if (height > 0) { |
| window.requestAnimationFrame(scrollToTop); |
| window.scrollTo(0, height - height / 8); |
| } |
| } |
12、滚动到元素位置
| export const smoothScroll = element =>{ |
| document.querySelector(element).scrollIntoView({ |
| behavior: 'smooth' |
| }); |
| }; |
示例:
13、uuid
| export const uuid = () => { |
| const temp_url = URL.createObjectURL(new Blob()) |
| const uuid = temp_url.toString() |
| URL.revokeObjectURL(temp_url) |
| return uuid.substring(uuid.lastIndexOf('/') + 1) |
| } |
示例:
不过要吐槽一句的是,uuid一般应由后端来进行生成
14、金额格式化
参数:
- {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) |
| } |
示例:
| moneyFormat(10000000) |
| moneyFormat(10000000, 3, '.', '-') |
15、存储操作
| 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 |
| } |
| } |
| |
| const localCache = new MyCache() |
| const sessionCache = new MyCache(false) |
| |
| export { localCache, sessionCache } |
示例:
| localCache.getItem('user') |
| sessionCache.setItem('name','树哥') |
| sessionCache.getItem('token') |
| localCache.clear() |
16、下载文件
参数:
- 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) |
| } |
| |
| 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); |
| }) |
| }` |
| |
使用:
| downloadFile('/api/download', {id}, '文件名') |
17、时间操作
关于时间操作,没必要自己再写一大串代码了,强烈推荐使用 day.js[2]
Day.js 是一个仅 2kb 大小的轻量级 JavaScript 时间日期处理库,下载、解析和执行的JavaScript更少,为代码留下更多的时间。
18、深拷贝
| 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")) { |
| |
| child = new Date(parent.getTime()); |
| } else { |
| |
| proto = Object.getPrototypeOf(parent); |
| |
| 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); |
| }; |
此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。
如果确实想要完备的深拷贝,推荐使用 lodash 中的 cloneDeep 方法。
19、模糊搜索
参数:
- 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 |
| } |
示例:
| const list = [ |
| { id: 1, name: '树哥' }, |
| { id: 2, name: '黄老爷' }, |
| { id: 3, name: '张麻子' }, |
| { id: 4, name: '汤师爷' }, |
| { id: 5, name: '胡万' }, |
| { id: 6, name: '花姐' }, |
| { id: 7, name: '小梅' } |
| ] |
| fuzzyQuery(list, '树', 'name') |
20、遍历树节点
| 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) |
| } |
| } |
| } |
示例:
假设我们要从树状结构数据中查找 id 为 9 的节点
| const treeData = [{ |
| id: 1, |
| label: '一级 1', |
| children: [{ |
| id: 4, |
| label: '二级 1-1', |
| children: [{ |
| id: 9, |
| label: '三级 1-1-1' |
| }, { |
| id: 10, |
| label: '三级 1-1-2' |
| }] |
| }] |
| }, { |
| id: 2, |
| label: '一级 2', |
| children: [{ |
| id: 5, |
| label: '二级 2-1' |
| }, { |
| id: 6, |
| label: '二级 2-2' |
| }] |
| }, { |
| id: 3, |
| label: '一级 3', |
| children: [{ |
| id: 7, |
| label: '二级 3-1' |
| }, { |
| id: 8, |
| label: '二级 3-2' |
| }] |
| }], |
| |
| let result |
| foreachTree(data, (item) => { |
| if (item.id === 9) { |
| result = item |
| } |
| }) |
| console.log('result', result) // {id: 9,label: "三级 1-1-1"} |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步