总结一些工作中常用到的utils,希望能帮助到大家,增加摸鱼时间
getHidePhone
获取脱敏号码
ts
/**
* @description 隐藏手机号
* @param {String} content 内容
* @param {Number} hideLen 要隐藏的长度,默认为4
* @param {String} symbol 符号,默认为*
* @param {String} padStartOrEnd 如果平分的长度为奇数,多出的一位填充的位置,默认为end
* @param {Boolean} removeNan 是否移除非数字,默认为true
* @returns {String} 隐藏后的内容
*/
export const getHidePhone = (
content: string,
hideLen = 4,
symbol = '*',
padStartOrEnd: 'start' | 'end' = 'end',
removeNan = true,
) => {
// 如果需要先移除非数字
if (removeNan) {
content = content.replace(/[^\d]/g, '')
}
const contentLen = content.length
// 不是字符串、空字符串、要隐藏的长度为0直接返回原始字符串
if (getTypeOf(content) !== 'String' || !contentLen || !hideLen) return content
// 隐藏长度大于等于内容长度,直接返回原始字符串长度的符号
if (contentLen <= hideLen)
return content.replace(new RegExp(`\\d{1}`, 'g'), '*')
const remainingLen = contentLen - hideLen
const splitLen = Math.floor(remainingLen / 2)
let start = splitLen
let end = splitLen
if (remainingLen % 2 === 1) {
if (padStartOrEnd === 'start') {
start += 1
} else {
end += 1
}
}
return content.replace(
new RegExp(`^(\\d{${start}})\\d{${hideLen}}(\\d{${end}})$`),
`$1${symbol.repeat(hideLen)}$2`,
)
}
console.log(getHidePhone('15108324289')) // 151****4289
console.log(getHidePhone('151')) // ***
console.log(getHidePhone('1510')) // ***0
console.log(getHidePhone('')) // ''
console.log(getHidePhone('15108324289', 6)) // 15******289
console.log(getHidePhone('15108324289', 40)) // ***********
console.log(getHidePhone('15108324289', undefined, '-')) // 151----4289
console.log(getHidePhone('15108324289', undefined, undefined, 'start')) // 1510****289
console.log(getHidePhone('15108324289', undefined, undefined, 'end')) // 151****4289
console.log(getHidePhone('151-083%#2 4289', undefined, undefined)) // 151****4289
console.log(
getHidePhone('151-083%#2 4289', undefined, undefined, undefined, false),
) // 151-083%#2 4289
formateContentBySymbol
格式化内容,根据符号进行格式化,常用于千分位分割
ts
/**
* @description 格式化内容,根据符号进行格式化
* @param {String} content 内容
* @param {String} symbol 符号
* @param {Number} gap 符号之间的间距,默认3个空格
* @returns {String} 格式化后的内容
*/
export const formateContentBySymbol = (
content: string,
symbol: string,
gap = 3,
) => {
return content.replace(new RegExp(`(\\d{${gap}})(?=\\d)`, 'g'), `$1${symbol}`)
}
/**
* @description 格式化内容,根据符号进行格式化
* @param {String} content 内容
* @param {String} symbol 符号
* @param {Number} gap 符号之间的间距,默认3个空格
* @returns {String} 格式化后的内容
*/
export const formateContentBySymbol2 = (
content: string,
symbol: string,
gap = 3,
) => {
return content.replace(new RegExp(`\\B(?=(\\d{${gap}})+$)`, 'g'), symbol)
}
/**
* @description 格式化内容,根据符号进行格式化
* @param {String} content 内容
* @param {String} symbol 符号
* @param {Number} gap 符号之间的间距,默认3个空格
* @returns {String} 格式化后的内容
*/
export const formateContentBySymbol3 = (
content: string,
symbol: string,
gap = 3,
) => {
return content.replace(
new RegExp(`(\\d)(?=(\\d{${gap}})+$)`, 'g'),
`$1${symbol}`,
)
}
console.log(formateContentBySymbol('235789075433254321', ',')) // 235,789,075,433,254,321
console.log(formateContentBySymbol2('235789075433254321', ',', 7)) // 2357,8907543,3254321
console.log(formateContentBySymbol3('235789075433254321', ',', 2)) // 23,57,89,07,54,33,25,43,21
zeroNDigitMDecimalReg
0或者n位的数字,最多m位小数正则
ts
/**
* @desc 0或者n位的数字,最多m位小数
* @param n n位的数字
* @param m 最多m位小数
* @returns {RegExp} 返回正则表达式
*/
export const zeroNDigitMDecimalReg = (n = 4, m = 2): RegExp => {
if (!m) {
// 没有小数位的情况
return new RegExp(`^(0|([1-9][0-9]{0,${n - 1}}))$`)
}
// 一位小数位的情况
if (m === 1) {
return new RegExp(`^(0(\\.[1-9])?|([1-9][0-9]{0,${n - 1}}(\\.[1-9])?))$`)
}
// 二位小数位的情况
if (m === 2) {
return new RegExp(
`^(0(\\.(([1-9]{1,2})|0[1-9]))?|([1-9][0-9]{0,${
n - 1
}}(\\.(([1-9]{1,2})|0[1-9]))?))$`,
)
}
// 二位以上小数位的情况
return new RegExp(
`^(0(\\.(([1-9]{1,${m - 1}})|([0-9]{1,${m - 1}}[1-9]?)))?|([1-9][0-9]{0,${
n - 1
}}(\\.(([1-9]{1,${m - 1}})|([0-9]{1,${m - 1}}[1-9]?)))?))$`,
)
}
console.log(zeroNDigitMDecimalReg(4, 2).test('123456789.123456789')) // false
console.log(zeroNDigitMDecimalReg(4, 10).test('1232.123456789')) // true
console.log(zeroNDigitMDecimalReg(4, 2).test('1234.1')) // true
console.log(zeroNDigitMDecimalReg(8, 6).test('13323234.000001')) // true
console.log(zeroNDigitMDecimalReg(8, 6).test('13323234.0000001')) // false
nDigitReg
0或者n位的整数正则
ts
/**
* @desc 0或者n位的整数正则
* @param n 最多n位的数字
* @param with0 是否包含0
* @returns {RegExp} 返回正则表达式
*/
export const nDigitReg = (n = 4, with0?: boolean) => {
if (with0) {
// 包含0的情况
return new RegExp(`^(0|([1-9][0-9]{0,${n - 1}}))$`)
}
// 不包含0的情况
return new RegExp(`^[1-9][0-9]{0,${n - 1}}$`)
}
console.log(nDigitReg(4).test('1234')) // true
console.log(nDigitReg(6).test('1234')) // true
console.log(nDigitReg(6).test('123456789')) // false
console.log(nDigitReg().test('1234.56789')) // false
console.log(nDigitReg(undefined, true).test('0')) // true
console.log(nDigitReg(undefined).test('0')) // false
onetonnine
1-9xxxx n个9
ts
/**
* @desc 1-9xxxx n个9
* @param n n位,一共多少位数字
*/
export const onetonnine = (n = 3) => {
return new RegExp(`^[1-9][0-9]{0,${n - 1}}$`)
}
console.log(onetonnine(4).test('1234')) // true
console.log(onetonnine(4).test('123')) // true
console.log(onetonnine(4).test('12343')) // false
zerotonnine
0-9xxxx n个9
ts
/**
* @desc 0-9xxxx n个9
* @param n n位,一共多少位数字
*/
export const zerotonnine = (n = 3) => {
return new RegExp(`^(0|([1-9][0-9]{0,${n - 1}}))$`)
}
console.log(zerotonnine(4).test('1234')) // true
console.log(zerotonnine(4).test('123')) // true
console.log(zerotonnine(4).test('12343')) // false
console.log(zerotonnine().test('0')) // true
zerotonnine2Decimal
0-9xxxx n个9, 最多两位小数
ts
/**
* @description 0-9xxxx n个9, 最多两位小数
* @param {Number} n n位,一共多少位数字,默认4位数
* @returns {RegExp} 正则
*/
export const zerotonnine2Decimal = (n = 4) => {
return new RegExp(
`^(0(\\.(([1-9]{1,2})|0[1-9]))?|([1-9][0-9]{0,${
n - 1
}}(\\.(([1-9]{1,2})|0[1-9]))?))$`,
)
}
console.log(zerotonnine2Decimal(4).test('1234')) // true
console.log(zerotonnine2Decimal().test('1234')) // true
console.log(zerotonnine2Decimal().test('1234.00')) // false
console.log(zerotonnine2Decimal().test('1234.01')) // true
console.log(zerotonnine2Decimal().test('1234.1')) // true
console.log(zerotonnine2Decimal().test('1234.10')) // false
console.log(zerotonnine2Decimal().test('1234.001')) // false
console.log(zerotonnine2Decimal(6).test('123456789')) // false
console.log(zerotonnine2Decimal(6).test('0')) // true
console.log(zerotonnine2Decimal(6).test('0.01')) // true
onetonnine2Decimal
1-9xxxx n个9, 最多两位小数
ts
/**
* @description 1-9xxxx n个9, 最多两位小数
* @param {Number} n n位,一共多少位数字,默认4位数
* @returns {RegExp} 正则
*/
export const onetonnine2Decimal = (n = 4) => {
return new RegExp(`^[1-9][0-9]{0,${n - 1}}(\\.(([1-9]{1,2})|0[1-9]))?$`)
}
console.log(onetonnine2Decimal(4).test('1234')) // true
console.log(onetonnine2Decimal().test('1234')) // true
console.log(onetonnine2Decimal().test('1234.00')) // false
console.log(onetonnine2Decimal().test('1234.01')) // true
console.log(onetonnine2Decimal().test('1234.1')) // true
console.log(onetonnine2Decimal().test('1234.10')) // false
console.log(onetonnine2Decimal().test('1234.001')) // false
console.log(onetonnine2Decimal(6).test('123456789')) // false
console.log(onetonnine2Decimal(6).test('0')) // false
console.log(onetonnine2Decimal(6).test('0.01')) // false
setCliboardContent
复制文本的通用函数
ts
/**
* @description 复制文本的通用函数
* @param {String} content 要复制的内容
*/
export function setCliboardContent(content?: string) {
if (!content) return
const selection = window.getSelection()
if (selection?.rangeCount) {
selection?.removeAllRanges()
}
const el = document.createElement('textarea')
el.value = content || ''
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
el.select()
document.execCommand('copy')
el.remove()
}
getCliboardValue
获取剪切板中的内容
ts
/**
* @description 获取剪切板中的内容
* @returns 剪切板内容
*/
export function getCliboardValue() {
const el = document.createElement('input')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
el.select()
document.execCommand('paste')
// 获取文本输入框中的值
const clipboardValue = el.value
el.remove()
return clipboardValue
}
delay
延迟执行
ts
/**
* @description 延迟执行
* @param wait 延迟时间
* @returns
*/
export function delay(wait = 1000) {
return new Promise((resolve) => setTimeout(resolve, wait))
}
getTypeOf
获取数据类型
ts
/**
* @description 获取数据类型
* @param data
* @returns {String} 获取到的数据类型
*/
export function getTypeOf(data: any) {
return Object.prototype.toString.call(data).slice(8, -1)
}
trimStart
去除字符串开头的空格
ts
/**
* @description 去除字符串开头的空格
* @param {String} str 要处理的字符串
* @returns {String} 去除空格后的字符串
*/
export const trimStart = (str: string) => {
if (getTypeOf(str) !== 'String') {
return str
}
return str?.replace(/^(\s+)(.*)$/g, '$2')
}
trimEnd
去除字符串结尾的空格
ts
/**
* @description 去除字符串结尾的空格
* @param {String} str 要处理的字符串
* @returns {String} 去除空格后的字符串
*/
export const trimEnd = (str: string) => {
if (getTypeOf(str) !== 'String') {
return str
}
return str?.replace(/^(.*)(\s+)$/g, '$1')
}
trimAll
去除字符串中的所有空格
ts
/**
* @description 去除字符串中的所有空格
* @param {String} str 要处理的字符串
* @returns {String} 去除空格后的字符串
*/
export const trimAll = (str: string) => {
if (getTypeOf(str) !== 'String') {
return str
}
return str?.replace(/\s+/g, '')
}
compressPic
压缩图片
ts
/**
* @description 压缩图片
* @param {File} file 要处理的图片文件
* @param {Number} quality 压缩质量
* @returns {Promise<File | Blob>} 压缩后的图片文件
*/
export async function compressPic(
file: File,
quality = 0.6,
): Promise<File | Blob> {
return new Promise((resolve) => {
try {
const reads = new FileReader()
reads.readAsDataURL(file)
reads.onload = ({ target }) => {
// 这里quality的范围是(0-1)
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')!
const img = new Image()
img.src = (target as any)?.result
img.onload = function () {
const width = img.width
const height = img.height
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
// 转换成base64格式 quality为图片压缩质量 0-1之间 值越小压缩的越大 图片质量越差
canvas.toBlob(
(blob) => {
resolve(blob!)
},
file.type,
quality,
)
}
}
reads.onerror = () => {
resolve(file)
}
} catch {
resolve(file)
}
})
}
randomString
生成指定长度的随机字符串
ts
/**
* @description 生成指定长度的随机字符串
* @param {Number} length 输出字符串的长度
* @param {Number} radix 字符串的基数,默认为36(包括0-36)
* @returns 返回指定长度的随机字符串,全部为大写
*/
export const randomString = (length: number, radix = 36) => {
// 生成一个随机字符串,基数为radix,并去除前两位"0."
let str = Math.random().toString(radix).substring(2)
// 如果生成的字符串长度大于等于所需长度,则截取前length个字符并转为大写
if (str.length >= length) {
return str.substring(0, length).toLocaleUpperCase()
}
// 如果字符串长度不足,递归调用自身以生成剩余长度的字符串,并拼接到原字符串上
str += randomString(length - str.length, radix)
// 将最终字符串转为大写并返回
return str.toLocaleUpperCase()
}
scrollToBottom
滚动到底部
ts
/**
* @description 滚动到底部
* @param {String} selector 类名
*/
export const scrollToBottom = (selector?: string) => {
const domWrapper = selector
? document.querySelector(selector)
: document.documentElement || document.body // 外层容器 出现滚动条的dom
if (domWrapper) {
domWrapper.scrollTo({ top: domWrapper.scrollHeight, behavior: 'smooth' })
}
}
scrollToTop
滚动到顶部
ts
/**
* @description 滚动到顶部
* @param {String} selector 类名
*/
export const scrollToTop = (selector?: string) => {
const domWrapper = selector
? document.querySelector(selector)
: document.documentElement || document.body // 外层容器 出现滚动条的dom
if (domWrapper) {
domWrapper.scrollTo({ top: 0, behavior: 'smooth' })
}
}
isJSON
判断是否为JSON字符串
ts
/**
* @description 判断是否为JSON字符串
* @param {String} str 字符串
* @returns {Boolean} 是否为JSON字符串
*/
export function isJSON(str: string) {
if (typeof str !== 'string') {
// 1、传入值必须是 字符串
return false
}
try {
const obj = JSON.parse(str) // 2、仅仅通过 JSON.parse(str),不能完全检验一个字符串是JSON格式的字符串
if (typeof obj === 'object' && obj) {
//3、还必须是 object 类型
return true
}
return false
} catch {
return false
}
}
getRandomIntInclusive
生成指定范围内的随机整数(包含最小值和最大值)
ts
/**
* 生成指定范围内的随机整数(包含最小值和最大值)
* @param min 最小值(包含)
* @param max 最大值(包含)
* @returns 指定范围内的随机整数
*/
export function getRandomIntInclusive(
min: number = 1,
max: number = 100,
): number {
return Math.floor(Math.random() * (max - min + 1)) + min
}