Vue 开发常用方法记录

64 阅读3分钟

默认方法

取得 [n, m] 范围内随机整数

function randomFullClose(min: number, max: number): number {
  if (min > max) throw new Error(`min must be less than max!`)
  return Math.floor(Math.random() * (max - min + 1) + min)
}

延时函数 指定 ms 后再执行后续函数

function sleep(delay = 1000): Promise<void> {
  return new Promise((resolve, _) => setTimeout(() => resolve(), delay))
}

利用 a 标签进行下载

/**
 * 利用 a 标签进行下载
 * @param {String} fileURL
 * @param {String} fileName
 */
function linkDownload(fileURL: string, fileName = Date.now().toString()): void {
  const a = document.createElement('a')
  a.style.position = 'relative' // 确保临时元素不会显示在页面中
  a.style.left = '-999999px'
  a.style.top = '-999999px'
  a.href = fileURL
  a.download = fileName
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

ArrayBuffer 转 Blob

/**
 * ArrayBuffer 转 Blob
 * @param {Buffer} buffer 待转换的 ArrayBuffer 数据
 * @param {String} blobType 目标 Blob 的数据 MIME 类型
 * @returns {Blob} 转换后的 Blob 数据
 */
function arrayBufferToBlob(buffer: ArrayBuffer, blobType = 'application/actet-stream'): Blob {
  const unit8Array = new Uint8Array(buffer)
  return new Blob([unit8Array], { type: blobType })
}

图片转为 Base64 字符串

/**
 * 图片转为 Base64 字符串
 * @param {String} imgURL 待转换的图片路径
 * @param {String} type 转换后的图片类型
 * @param  {Number} quality 转换后的图片质量
 * @returns {String} Base64 字符串
 */
 function imageToBase64(imgURL: string, mimeType: 'image/jpeg' | 'image/png' | 'image/webp' = 'image/jpeg', quality = 1): Promise<string> {
  const img = new Image()
  // 因为是网络资源所以会有图片跨域问题产生,此属性可以解决跨域问题
  img.setAttribute('crossOrigin', 'anonymous')
  // 如果需要兼容 iOS,这两个顺序一定不能换,先设置 crossOrigin 后设置 src
  img.src = imgURL
  return new Promise((resolve, reject) => {
    img.onload = () => {
      const cvs = document.createElement('canvas')
      cvs.width = img.width
      cvs.height = img.height
      const ctx = cvs.getContext('2d')!
      ctx.drawImage(img, 0, 0, cvs.width, cvs.height)
      resolve(cvs.toDataURL(mimeType, quality))
    }
    img.onerror = (error: any) => reject(error)
  })
}

复制文本到剪贴板

function copyText(text: string): void {
  // 是否支持 navigator.clipboard 属性
  const isClipboardApiSupported = window.navigator && window.navigator.clipboard
  if (isClipboardApiSupported) {
    window.navigator.clipboard.writeText(text)
  } else {
    const textarea = document.createElement('textarea')
    textarea.readOnly = true
    textarea.value = text
    textarea.style.position = 'absolute'
    textarea.style.top = '-9999px'
    textarea.style.left = '-9999px'
    document.body.appendChild(textarea)
    textarea.select()
    document.execCommand('copy')
    textarea.remove()
  }
}

防抖函数

/** 任意类型的 Function */
type AnyFunction = (...args: any[]) => any
/** 表示防抖后的函数类型 */
type DebouncedFunction<T extends AnyFunction> = (...args: Parameters<T>) => ReturnType<T>

function debounce<T extends AnyFunction>(callback: T, delay: number, immediate = false) {
  // 通过闭包缓存一个定时器 id
  let timer: NodeJS.Timeout | null

  const _debounce = function (this: ThisParameterType<T>, ...args: Parameters<T>) {
    // 如果已经设定过定时器就清空上一次的定时器
    if (timer) clearTimeout(timer)

    // 如果需要立即执行,且之前未执行过,则立即执行原始函数
    if (immediate && !timer) {
      callback.apply(this, args)
      timer = setTimeout(() => (timer = null), delay)
    } else {
      // 设置新的定时器,在延迟结束时执行原始函数
      // 使用保存的上下文和参数执行原始函数 箭头函数 所以可以直接用上级作用域的值
      timer = setTimeout(() => {
        timer = null
        callback.apply(this, args)
      }, delay)
    }
  }

  // 返回防抖后的函数,并根据原始函数的类型来断言返回函数的类型
  return _debounce as DebouncedFunction<T>
}

节流函数

/** 任意类型的 Function */
type AnyFunction = (...args: any[]) => any
/** 表示节流后的函数类型 */
type ThrottledFunction<T extends AnyFunction> = T

function throttle<T extends AnyFunction>(callback: T, delay: number) {
  let timestamp = Date.now()
  const _throttle = function (this: ThisParameterType<T>, ...args: Parameters<T>) {
    const now = Date.now()
    if (Date.now() - timestamp > delay) {
      callback.apply(this, args)
      timestamp = now
    }
  }
  return _throttle as ThrottledFunction<T>
}

校验方法

校验是否为手机号

function isPhone(phone: string): boolean {
  const reg = /^1[3-9]\d{9}$/
  return reg.test(phone)
}

校验是否为 QQ 号码

function isQQ(qq: string): boolean {
  const reg = /^[1-9]\d{4,10}$/
  return reg.test(qq)
}

判断是否为 Email(支持中文邮箱)

function isEmail(email: string): boolean {
  const reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
  return reg.test(email)
}

校验对象是否为空

function isEmptyObject(obj: Record<string, any>): boolean {
  return Reflect.ownKeys(obj).length === 0 && JSON.stringify(obj) === '{}'
}

判断版本号格式是否为 X.Y.Z

function isVersion(version: string): boolean {
  const reg = /^\d+(?:\.\d+){2}$/
  return reg.test(version)
}

判断是否为车牌(兼容新能源车牌)

function isLicensePlate(plate: string): boolean {
  const reg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$/
  return reg.test(plate)
}

判断是否为第二代身份证(18 位)

function isChineseIdCard(content: string): boolean {
  const reg = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/
  return reg.test(content)
}

判断是否为 MAC 地址

function isMac(mac: string): boolean {
  const reg = /^(([a-f0-9][0,2,4,6,8,a,c,e]:([a-f0-9]{2}:){4})|([a-f0-9][0,2,4,6,8,a,c,e]-([a-f0-9]{2}-){4}))[a-f0-9]{2}$/i
  return reg.test(mac)
}

检验是否为 IPv4 地址

function isIPv4(ip: string): boolean {
  const reg = /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/
  return reg.test(ip)
}

判断是否为网址(带协议)

function isUrl(url: string): boolean {
  const reg = /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/
  return reg.test(url)
}

判断是否为域名(不带协议)

function isDomain(domain: string): boolean {
  const reg = /^([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})$/
  return reg.test(domain)
}

判断是否为网址或 IP(带端口)

function isUrlPort(url: string): boolean {
  const reg = /^((ht|f)tps?:\/\/)?[\w-]+(\.[\w-]+)+:\d{1,5}\/?$/
  return reg.test(url)
}

校验是否为外链

function isExternal(path: string): boolean {
  const reg = /^(https?:|mailto:|tel:)/
  return reg.test(path)
}

判断时间格式是否为 24 小时制(HH:mm:ss)

function is24H(time: string): boolean {
  const reg = /^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/
  return reg.test(time)
}

校验是否是中文汉字

function isChinese(str: string): boolean {
  const reg = /[\u0391-\uFFE5A-Za-z]+$/
  return reg.test(str)
}

判断浏览器是否支持 webp 格式图片

function isSupportWebp(): boolean {
  return !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') === 0
}

校验是否为十六进制颜色值

function isHexColor(color: string): boolean {
  const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/
  return reg.test(color)
}