基于ts写法的一些 项目中会有所用到的功能函数

项目中可能会用到的功能函数,一般定义到外部文件中,hooks中。在此记录一下:
一,判断是否ie浏览器 判断ie的版本

// 判断是否ie浏览器
export const isIE = function isIE() {
  if (!!window.ActiveXObject || 'ActiveXObject' in window) {
    return true
  }
  return false
}

// 判断 ie 的版本
export const IEVersion = function IEVersion() {
  const { userAgent } = navigator // 取得浏览器的userAgent字符串
  const isIE =
    userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 // 判断是否IE<11浏览器
  const isEdge = userAgent.indexOf('Edge') > -1 && !isIE // 判断是否IE的Edge浏览器
  const isIE11 =
    userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1
  if (isIE) {
    const reIE = /MSIE (\\d+\\.\\d+);/
    reIE.test(userAgent)
    const fIEVersion = parseFloat(RegExp.$1)
    if (fIEVersion === 7) {
      return 7
    }
    if (fIEVersion === 8) {
      return 8
    }
    if (fIEVersion === 9) {
      return 9
    }
    if (fIEVersion === 10) {
      return 10
    }
    return 6 // IE版本<=7
  }
  if (isEdge) {
    return 'edge' // edge
  }
  if (isIE11) {
    return 11 // IE11
  }
  return -1 // 不是ie浏览器
}

二,转意符换成普通字符

export const escape2Html = function escape2Html(str: string) {
  const arrEntities: any = { lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"' }
  return str.replace(
    /&(lt|gt|nbsp|amp|quot);/gi,
    (_all: any, t) => arrEntities[t]
  )
}

三,'yyyy-MM-dd HH:mm:ss’格式的字符串转日期

export const stringToDate = function stringToDate(str: string) {
  const tempStrs = str.split(' ')

  const dateStrs = tempStrs[0].split('-')

  const year = parseInt(dateStrs[0], 10)

  const month = parseInt(dateStrs[1], 10) - 1

  const day = parseInt(dateStrs[2], 10)

  const timeStrs = tempStrs[1] ? tempStrs[1].split(':') : []

  const hour = timeStrs[0] ? parseInt(timeStrs[0], 10) : 0

  const minute = timeStrs[1] ? parseInt(timeStrs[1], 10) : 0

  const second = timeStrs[2] ? parseInt(timeStrs[2], 10) : 0

  const date = new Date(year, month, day, hour, minute, second)

  return date
}

四,生成随机数

export const getUUID = function getUUID(len = 6, prefix = '') {
  if (len < 1 || len > 48) {
    len = 6
  }
  len = Number.isNaN(len) ? 6 : len
  const seed = '0123456789abcdefghijklmnopqrstubwxyzABCEDFGHIJKLMNOPQRSTUVWXYZ'
  const seedLen = seed.length - 1
  let uuid = ''
  // eslint-disable-next-line no-plusplus
  while (len--) {
    uuid += seed[Math.round(Math.random() * seedLen)]
  }
  return prefix + uuid
}

五,根据数组生成tree结构

export const setTreeData = function setTreeData(list: any, option: any) {
  const nlist = list
  const len = nlist.length
  const defaultOption: any = {
    rootId: '0', // rootId 的key
    key: 'id', // id的key
    pKey: 'pid', // pid的key
    // titleKey: 'title', // 重新设置key-value防止树找不到key
    // setTitleByKey: 'name' // 根据数据的key
  }
  if (option && option.titleKey && option.setTitleByKey) {
    // eslint-disable-next-line no-plusplus
    for (let i = 0; i < len; i++) {
      nlist[i][option.titleKey] = nlist[i][option.setTitleByKey]
    }
  }
  // 合并参数
  if (option) {
    for (const k in option) {
      defaultOption[k] = option[k]
    }
  }

  const result = []
  const itemMap: any = {}
  for (const item of nlist) {
    const id = item[defaultOption.key]
    const pid = item[defaultOption.pKey]

    if (!itemMap[id]) {
      itemMap[id] = {
        children: [],
      }
    }
    itemMap[id] = {
      ...item,
      children: itemMap[id].children,
    }
    const treeItem = itemMap[id]

    if (pid === defaultOption.rootId) {
      result.push(treeItem)
    } else {
      if (!itemMap[pid]) {
        itemMap[pid] = {
          children: [],
        }
      }
      itemMap[pid].children.push(treeItem)
    }
  }
  return result
}

六,判断两个对象是否完全相等 数组去重 数字滚动效果

// 判断两个对象是否相等
export const dataischange = function dataischange(e1: object, s1: object) {
  let ischange = false
  function f(e: any, s: any) {
    for (const k in e) {
      if (e[k] && typeof e[k] === 'object') {
        f(e[k], s[k])
      } else {
        // 判断参数发生了变化
        // eslint-disable-next-line no-lonely-if
        if (e[k] !== s[k]) {
          ischange = true
          return
        }
      }
    }
  }
  f(e1, s1)
  return ischange
}

// 数组去重
export const uniqueArr = function uniqueArr(array: []) {
  const n: any = [] // 一个新的临时数组
  // 遍历当前数组
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < array.length; i++) {
    // 如果当前数组的第i已经保存进了临时数组,那么跳过,
    // 否则把当前项push到临时数组里面
    if (n.indexOf(array[i]) === -1) n.push(array[i])
  }
  return n
}

// 数组项为对象时,采用对象key-value进行去重
export const uniqueArrWithKey = function uniqueArrWithKey(
  array: any,
  key: string | number
) {
  const n = []
  const r = [] // 一个新的临时数组
  // 遍历当前数组
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < array.length; i++) {
    // 如果当前数组的第i已经保存进了临时数组,那么跳过,
    // 否则把当前项push到临时数组里面
    if (n.indexOf(array[i][key]) === -1) {
      n.push(array[i][key])
      r.push(array[i])
    }
  }
  return r
}

// 数字滚动效果
export const scrollToNum = function scrollToNum(el: any, orgin: any, target: any, time = 1) {
  const increase = target - orgin > 0
  let speed = 1
  speed = increase ? speed : -speed
  el.innerText = orgin
  let intervalTime = (time * 1000) / ((target - orgin) / speed)
  if (intervalTime < 10) {
    intervalTime = 10
    speed = (target - orgin) / ((time * 1000) / intervalTime)
  }
  const timer = setInterval(() => {
    orgin += speed
    el.innerText = parseInt(orgin, 10)
    if ((increase && orgin >= target) || (!increase && orgin <= target)) {
      el.innerText = parseInt(target, 10)
      clearInterval(timer)
    }
  }, intervalTime)
}

七,验证身份证号 的两种方式, 验证手机号

// 验证身份证号
export const checkIdcard = function checkIdcard(idcard: string) {
  const checkProv = function checkProv(val: string) {
    const pattern = /^[1-9][0-9]/
    const provs: any = {
      11: '北京',
      12: '天津',
      13: '河北',
      14: '山西',
      15: '内蒙古',
      21: '辽宁',
      22: '吉林',
      23: '黑龙江 ',
      31: '上海',
      32: '江苏',
      33: '浙江',
      34: '安徽',
      35: '福建',
      36: '江西',
      37: '山东',
      41: '河南',
      42: '湖北 ',
      43: '湖南',
      44: '广东',
      45: '广西',
      46: '海南',
      50: '重庆',
      51: '四川',
      52: '贵州',
      53: '云南',
      54: '西藏 ',
      61: '陕西',
      62: '甘肃',
      63: '青海',
      64: '宁夏',
      65: '新疆',
      71: '台湾',
      83: '台湾',
      81: '香港',
      82: '澳门',
    }
    if (pattern.test(val)) {
      if (provs[val]) {
        return true
      }
    }
    return false
  }

  const checkDate = function checkDate(val: string) {
    const pattern =
      /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/
    if (pattern.test(val)) {
      const year = val.substring(0, 4)
      const month = val.substring(4, 6)
      const date = val.substring(6, 8)
      const date2 = new Date(`${year}-${month}-${date}`)
      if (date2 && date2.getMonth() === parseInt(month, 10) - 1) {
        return true
      }
    }
    return false
  }

  const checkCode = function checkCode(val: string) {
    const p =
      /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
    const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
    const code = val.substring(17)
    if (p.test(val)) {
      let sum = 0
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < 17; i++) {
        sum += (val[i] as any) * factor[i]
      }
      if (parity[sum % 11] === code.toUpperCase()) {
        return true
      }
    }
    return false
  }

  const checkID = function checkID(val: string) {
    if (checkCode(val)) {
      const date = val.substring(6, 14)
      if (checkDate(date)) {
        if (checkProv(val.substring(0, 2))) {
          return true
        }
      }
    }
    return false
  }

  return checkID(idcard)
}

export const isValidIdCard = function (idCard: string, isIdCard?: boolean) {
  if (!isIdCard) return true
  let ret = false
  const w: any = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  if (idCard.length === 18) {
    // 身份证号码长度必须为18,只要校验位正确就算合法
    const crc = idCard.substring(17)
    // eslint-disable-next-line no-array-constructor
    const a = []
    let sum = 0
    // eslint-disable-next-line no-plusplus
    for (let i = 0; i < 17; i++) {
      a.push(idCard.substring(i, i + 1))
      sum += parseInt(a[i], 10) * parseInt(w[i], 10)
      // alert(a[i]);
    }
    sum %= 11
    let res = '-1'
    // eslint-disable-next-line default-case
    switch (sum) {
      case 0: {
        res = '1'
        break
      }
      case 1: {
        res = '0'
        break
      }
      case 2: {
        res = 'X'
        break
      }
      case 3: {
        res = '9'
        break
      }
      case 4: {
        res = '8'
        break
      }
      case 5: {
        res = '7'
        break
      }
      case 6: {
        res = '6'
        break
      }
      case 7: {
        res = '5'
        break
      }
      case 8: {
        res = '4'
        break
      }
      case 9: {
        res = '3'
        break
      }
      case 10: {
        res = '2'
        break
      }
    }
    if (crc.toLowerCase() === res.toLowerCase()) {
      ret = true
    }
    // ret=true;
  }
  /*
  else if(idCard.length == 15){
       //15位的身份证号,只验证是否全为数字
       var pattern = /\d/;
       ret=pattern.test(idCard);
  } */
  return ret
}

// 验证手机号码
export const checkMobilePhoneNumber = function checkMobilePhoneNumber(
  phone: string
) {
  if (/^1[3456789]\d{9}$/.test(phone)) {
    return true
  }
  return false
}

八,文件转为链接,base64转为blob,blob转为file,

// 文件转成链接
export const getObjectURL = function getObjectURL(file: any) {
  let url = null
  if (window.createObjectURL !== undefined) {
    // basic
    url = window.createObjectURL(file)
  } else if (window.URL !== undefined) {
    // mozilla(firefox)
    url = window.URL.createObjectURL(file)
  } else if (window.webkitURL !== undefined) {
    // webkit or chrome
    url = window.webkitURL.createObjectURL(file)
  }
  return url
}

// 将base64转换为blob
export const dataURLtoBlob = function dataURLtoBlob(dataurl: any) {
  const arr = dataurl.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  // eslint-disable-next-line no-plusplus
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

// 将blob转换为file
export const blobToFile = function blobToFile(theBlob: any, fileName?: any) {
  theBlob.lastModifiedDate = new Date()
  theBlob.name =
    fileName || getUUID(32) + (theBlob.type && `.${theBlob.type.split('/')[1]}`)
  return theBlob
}

// 该方法需要调取上面两个方法
// base64转file
export const base64ToFile = function base64ToFile(base64: any) {
  return blobToFile(dataURLtoBlob(base64))
}


// 将base64转换为File  ie下有bug
export function base64ToFileNoIe(dataurl: any, fileName: string) {
  const arr = dataurl.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  const newFileName =
    fileName || getUUID(32) + (mime && `.${mime.split('/')[1]}`)
  // eslint-disable-next-line no-plusplus
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], newFileName, { type: mime })
}


/**
 * 根据图片的url转换对应的base64值
 * @param { String } imageUrl 如:http://xxxx/xxx.png
 * @returns base64取值
 */
export async function urlToBase64(imageUrl: string) {
  return new Promise((resolve, reject) => {
    let canvas: HTMLCanvasElement | null = document.createElement('canvas')
    const ctx: CanvasRenderingContext2D | null = canvas.getContext('2d')
    let img: HTMLImageElement | null = new Image()
    img.crossOrigin = 'Anonymous' // 解决Canvas.toDataURL 图片跨域问题
    img.src = imageUrl
    img.onload = function () {
      canvas!.height = img!.height
      canvas!.width = img!.width
      ctx!.fillStyle = '#fff' // canvas背景填充颜色默认为黑色
      ctx!.fillRect(0, 0, img!.width, img!.height)
      ctx!.drawImage(img!, 0, 0) // 参数可自定义
      const dataURL = canvas!.toDataURL('image/jpeg', 1) // 获取Base64编码
      resolve(dataURL)
      canvas = null // 清除canvas元素
      img = null // 清除img元素
    }
    img.onerror = function () {
      reject(new Error(`Could not load image at ${imageUrl}`))
    }
  })
}

九,判断某个数字是否为质数 及 某个自然数中的质数的个数

// 判断是否质数
export function isZhishu(num: any) {
  if (typeof num !== 'number') return new Error(`${num} is not a number`)
  if (Math.abs(num) > Number.MAX_SAFE_INTEGER)
    return new Error(`${num} is a overnum`)
  const end = Math.sqrt(Math.abs(num))
  // eslint-disable-next-line no-plusplus
  for (let i = 2; i <= end; i++) {
    if (num % i === 0) {
      return false
    }
  }
  return true
}

// 某个自然数中的质数个数
export function allZshishuInNum(num: any) {
  if (typeof num !== 'number') return new Error(`${num} is not a number`)
  if (Math.abs(num) > Number.MAX_SAFE_INTEGER)
    return new Error(`${num} is a overnum`)
  if (num === 2) return [2]
  if (num === 3) return [2, 3]
  const arr = [2, 3]
  for (let i = 3; i <= num; i += 2) {
    // eslint-disable-next-line no-plusplus
    for (let j = 1; j < arr.length; j++) {
      if (i % arr[j] !== 0) {
        if (j === arr.length - 1) {
          arr.push(i)
        }
      } else {
        break
      }
    }
  }
  return arr
}

十,其它

// 时间戳转化为对应时间格式
// eslint-disable-next-line consistent-return
export const parseStamp = function parseStamp(
  stamp = '' as string | number,
  toDay = 0
) {
  let date = null
  if (!stamp) {
    date = new Date()
  } else {
    date = new Date(stamp)
  }
  const year: any = date.getFullYear()
  let month: any = date.getMonth() + 1
  let day: any = date.getDate()
  const week: any = date.getDay()
  let hour: any = date.getHours()
  let min: any = date.getMinutes()
  let sec: any = date.getSeconds()
  if (month < 10) month = `0${month}`
  if (day < 10) {
    if (toDay === 7) {
      day = `0${day - 1}`
    } else {
      day = `0${day}`
    }
  } else if (day >= 10 && toDay === 7) {
    day -= 1
  } else if (day >= 10 && toDay !== 7) {
    // eslint-disable-next-line no-self-assign
    day = day
  }

  let weekData = ''
  switch (week) {
    case 1:
      weekData = '星期一'
      break
    case 2:
      weekData = '星期二'
      break
    case 3:
      weekData = '星期三'
      break
    case 4:
      weekData = '星期四'
      break
    case 5:
      weekData = '星期五'
      break
    case 6:
      weekData = '星期六'
      break
    case 7:
      weekData = '星期日'
      break
    default:
      weekData = ''
      break
  }

  if (hour < 10) hour = `0${hour}`
  if (min < 10) min = `0${min}`
  if (sec < 10) sec = `0${sec}`
  if (toDay === 1) {
    // eslint-disable-next-line no-useless-concat
    return `${year}-${month}-${day} ` + `00:00:00`
  }
  if (toDay === 2) {
    // eslint-disable-next-line no-useless-concat
    return `${year}-${month}-${day} ` + `23:59:59`
  }
  if (toDay === 3) {
    return `${year}-${month}-${day}`
  }
  if (toDay === 4) {
    // eslint-disable-next-line no-useless-concat
    return `${year}${month}${day}` + `000000`
  }
  if (toDay === 5) {
    // eslint-disable-next-line no-useless-concat
    return `${year}${month}${day}` + `235959`
  }
  if (toDay === 6) {
    return `${year}${month}`
  }
  if (toDay === 7) {
    return new Date(`${year}/${month}/${day}`)
    // eslint-disable-next-line eqeqeq
  }
  if (toDay === 8) {
    return year + month
  }
  if (toDay === 9) {
    return `${year}${month}`
  }
  if (toDay === 10) {
    return `${year}-${month}-${day} ${hour}:${min}:${sec}`
  }
  if (toDay === 11) {
    return `${year}/${month}/${day} ${hour}:${min}:${sec} ${weekData}`
  }
}

// 根据生日查询年龄
export default function getAge(strBirthday: string): number | string {
  let returnAge: number = 0
  const [bornYear, bornMoon, bornDay] = strBirthday.split('-')
  const nowDate = new Date()
  const nowYear = nowDate.getFullYear()
  const nowMoon = nowDate.getMonth() + 1
  const nowDay = nowDate.getDate()

  if (Number(bornYear) === nowYear) {
    returnAge = 0
    if (Number(bornMoon) > nowMoon) return ''
    if (Number(bornMoon) === nowMoon && Number(bornDay) > nowDay) return ''
  } else if (Number(bornYear) < nowYear) {
    returnAge = nowYear - Number(bornYear)
    if (Number(bornMoon) > nowMoon) returnAge -= 1
    else if (Number(bornMoon) === nowMoon && Number(bornDay) > nowDay)
      returnAge -= 1
  } else return ''
  return returnAge
}

// 根据身份证查询年龄
export function calculateAge(idNumber: string) {
  // 截取身份证号中的出生日期
  const birthdayStr = idNumber.slice(6, 14)

  // 将出生日期转换为Date对象
  const year = parseInt(birthdayStr.slice(0, 4), 10)
  const month = parseInt(birthdayStr.slice(4, 6), 10) - 1 // 月份需要减去1,因为月份从0开始计数
  const day = parseInt(birthdayStr.slice(6, 8), 10)

  const birthday = new Date(year, month, day)

  // 获取当前日期
  const now = new Date()

  // 计算年龄
  let age = now.getFullYear() - birthday.getFullYear()

  // 如果当前日期小于出生日期,年龄减1
  if (
    now.getMonth() < birthday.getMonth() ||
    (now.getMonth() === birthday.getMonth() &&
      now.getDate() < birthday.getDate())
  ) {
    // eslint-disable-next-line no-plusplus
    age--
  }

  return age
}


/**
 * @description 从源对象复制属性值到目标对象
 * @author Cola
 * @param {object} target 目标对象
 * @param {object} origin 源对象
 * @param {array | undefined} keys 嵌套的key值
 * @example target: {a: {value: 1}} origin: {a: 1} keys: ['value']
 */
export const setObjAttrVal = (
  target: any,
  origin: any,
  keys: [] | undefined
) => {
  for (const key in target) {
    const val = origin[key]
    if (key in origin) {
      if (keys) {
        keys.reduce((p, n, i) => {
          if (i === keys.length - 1) {
            p[keys[keys.length - 1]] = val
          }
          return p[n]
        }, target[key])
      } else {
        target[key] = val
      }
    }
  }
  return target
}


/**
 * 参数一: url
 * 参数二: 要截取参数名
 */
export const getQueryVariable = function getQueryVariable(
  query: any,
  variable: any
) {
  query = query || document.location.search
  let vars = query.split('?')[1]
  vars = vars.split('&')
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split('=')
    if (pair[0] === variable) {
      return pair[1]
    }
  }
  return undefined
}

到此总结结束,如果对你有帮助的话,谢谢点赞。(欢迎评论区留言,指出不足。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值