Redbattle
踩坑
环境
项目
配置
知识点
踩坑
环境
项目
配置
知识点
  • JS
    • CSS
    • tools
    2022-02-09

    JS

    # 颜色转换 16 进制转 rgba

    /**
     * 颜色转换16进制转rgba
     * @param {String} hex
     * @param {Number} opacity
     */
    export const hex2Rgba = (hex, opacity) => {
      if (!hex) hex = '#2c4dae'
      return (
        'rgba(' +
        parseInt('0x' + hex.slice(1, 3)) +
        ',' +
        parseInt('0x' + hex.slice(3, 5)) +
        ',' +
        parseInt('0x' + hex.slice(5, 7)) +
        ',' +
        (opacity || '1') +
        ')'
      )
    }
    

    # 去除 html 标签

    // 去除html标签
    export const htmlSafeStr = str => {
      return str.replace(/<[^>]+>/g, '')
    }
    
    export const htmlSafeStr = str => {
      return new DOMParser().parseFromString(str, 'text/html').body.textContent || ''
    }
    

    # url 转对象

    export const params2Obj = url => {
      const search = url.split('?')[1]
      if (!search) {
        return {}
      }
      return JSON.parse(
        '{"' +
          decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"').replace(/\+/g, ' ') +
          '"}'
      )
    }
    

    # 对象转 url

    export const obj2Params = query => {
      let link = ''
      if (!Object.keys(query).length) {
        return link
      }
      for (const k in query) {
        link += `${k}=${query[k]}&`
      }
      return link.slice(0, -1)
    }
    

    # 生成 uuid

    /**
     * 生成uuid
     * @param {number} len 生成指定长度的uuid
     * @param {number} radix uuid进制数
     */
    export const uuid = (len, radix) => {
      let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
      let uuid = [],
        i
      radix = radix || chars.length
      if (len) {
        for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
      } else {
        let r
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
        uuid[14] = '4'
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | (Math.random() * 16)
            uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
          }
        }
      }
      return uuid.join('')
    }
    

    # 判断数据类型

    export const dataType = value => {
      const str = Object.prototype.toString.call(value)
      return str.slice(8, -1)
    }
    

    # 数据格式化

    export const formatNumber = (num = 0, format, retain, level = 0) => {
      if (!num) {
        return '0'
      }
      if (level > format.length) {
        return '∞'
      }
      if (num * 1 > format[level].maxInt + 1 - 1 / 10 ** retain) {
        num = num / (format[level].maxInt + 1)
        return formatNumber(num, format, retain, ++level)
      } else {
        return `${num.toFixed(retain)}${format[level].ext}`
      }
    }
    
    // 数值格式化并追加中文单位
    export const formatNumberCn = (num, retain = 2) => {
      const format = [
        {
          ext: '',
          maxInt: 9999
        },
        {
          ext: '万',
          maxInt: 9999
        },
        {
          ext: '亿',
          maxInt: 9999
        }
      ]
      return formatNumber(num, format, retain)
    }
    
    // 数值格式化并追加拼音单位
    export const formatNumberPy = (num, retain = 2) => {
      const format = [
        {
          ext: '',
          maxInt: 999
        },
        {
          ext: 'k',
          maxInt: 9
        },
        {
          ext: 'w',
          maxInt: 9999
        },
        {
          ext: 'y',
          maxInt: 9999
        }
      ]
      return formatNumber(num, format, retain)
    }
    
    // 数字
    export const formatNumberIntl = (num, retain = 0) => {
      if (!num || isNaN(num * 1)) {
        return 0
      } else {
        return new Intl.NumberFormat('en-Us', {
          minimumFractionDigits: retain,
          maximumFractionDigits: retain
        }).format(num)
      }
    }
    
    // 百分比
    export const formatPercent = (num, retain = 2) => {
      if (!num || isNaN(num * 1)) {
        return '0%'
      } else {
        return new Intl.NumberFormat('en-Us', {
          style: 'percent',
          useGrouping: false,
          minimumFractionDigits: retain,
          maximumFractionDigits: retain
        }).format(num)
      }
    }
    
    // 进度百分比
    export const formatD2NProgress = (num, retain = 2) => {
      if (!num || isNaN(num * 1)) {
        return 0
      } else {
        return (num * 100).toFixed(retain)
      }
    }
    

    # 下载

    export const downloadFile = (name, data) => {
      const a = document.createElement('a')
      a.download = `${name}-${new Date().getTime()}.xlsx`
      // 文本类型
      const blob = new Blob([data])
      // text指需要下载的文本或字符串内容
      a.href = URL.createObjectURL(blob)
      // 会生成一个类似blob;http://1ocalhost:8080/d3958f5c-0777-0845-9dcf-2cb28783acaf 这样的URL字符串
      document.body.appendChild(a)
      a.click()
      a.remove()
    }
    

    # 缓存

    const CACHE_KEY = 'cache_key_'
    
    // 获取缓存
    const getCache = key => {
      return JSON.parse(localStorage.getItem(CACHE_KEY + key))
    }
    
    // 设置缓存
    const setCache = (key, value) => {
      return localStorage.setItem(CACHE_KEY + key, JSON.stringify(value))
    }
    
    // 删除缓存
    const removeCache = key => {
      return localStorage.removeItem(CACHE_KEY + key)
    }
    

    # 字符串加密

    // 引入依赖包
    import JSEncrypt from 'jsencrypt'
    
    export const strEncrypt = (str, pubKey) => {
      const Encrypt = new JSEncrypt()
      Encrypt.setPublicKey(pubKey)
      return Encrypt.encrypt(str)
    }
    

    # 防抖

    let timeout = null
    /**
     * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数,n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
     *
     * @param {Function} func 要执行的回调函数
     * @param {Number} wait 延时的时间
     * @param {Boolean} immediate 是否立即执行
     * @return null
     */
    export const debounce = (func, wait = 500, immediate = false) => {
      // 清除定时器
      if (timeout !== null) clearTimeout(timeout)
      // 立即执行,此类情况一般用不到
      if (immediate) {
        const callNow = !timeout
        timeout = setTimeout(() => {
          timeout = null
        }, wait)
        if (callNow) typeof func === 'function' && func()
      } else {
        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
        timeout = setTimeout(() => {
          typeof func === 'function' && func()
        }, wait)
      }
    }
    

    # 节流

    let timer
    let flag
    /**
     * 节流原理:在一定时间内,只能触发一次,n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
     *
     * @param {Function} func 要执行的回调函数
     * @param {Number} wait 延时的时间
     * @param {Boolean} immediate 是否立即执行
     * @return null
     */
    function throttle(func, wait = 500, immediate = true) {
      if (immediate) {
        if (!flag) {
          flag = true
          // 如果是立即执行,则在wait毫秒内开始时执行
          typeof func === 'function' && func()
          timer = setTimeout(() => {
            flag = false
          }, wait)
        }
      } else if (!flag) {
        flag = true
        // 如果是非立即执行,则在wait毫秒内的结束处执行
        timer = setTimeout(() => {
          flag = false
          typeof func === 'function' && func()
        }, wait)
      }
    }
    

    # txt 转 html

    // url:txt 文件地址
    export const txt2Html = url => {
      return new Promise((resolve, reject) => {
        fetch(new Request(url))
          .then(response => {
            return response.blob()
          })
          .then(blob => {
            const reader = new FileReader()
            reader.readAsText(blob, 'utf-8')
            reader.onload = e => {
              if (e.target?.result) {
                resolve(e.target.result)
              } else {
                reject()
              }
            }
          })
          .catch(() => {
            reject()
          })
      })
    }
    

    # 上传本地文件

    export const uploadLocal = () => {
      const url = require('./1.jpg')
      return new Promise((resolve, reject) => {
        fetch(new Request(url))
          .then(response => {
            return response.blob()
          })
          .then(blob => {
            const form = new FormData()
            form.append('file', blob, 'file.jpg')
            // 上传方法
            // uploadImg(form).then()
          })
          .catch(() => {
            reject()
          })
      })
    }
    

    # 关键词高亮

    export const highlight = (text, keyword, color = '#f00') => {
      if (keyword && text && typeof text === 'string') {
        try {
          // 处理高亮的特殊字符
          const kw = keyword.replace(/(\$|\\|\^|\*|\+|\?\|\.|\||\(|\)|\[|\]|\{|\}|\\\\)/g, '\\$&')
          return text.replace(new RegExp(kw, 'img'), v => {
            return `<span style="color: ${color}">${v}</span>`
          })
        } catch (e) {
          console.log('highlight catch', e)
          return text
        }
      } else {
        return text
      }
    }
    
    最近更新
    01
    烧虾球
    05-13
    02
    二次开发
    12-20
    03
    文字展开收起
    10-17
    更多文章>
    Theme by Vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式