函数防抖、节流、深拷贝、对象属性深度合并等等方法

1、安装插件xe-utils

2、引入import XEUtils from 'xe-utils'

/**
 * 函数防抖
 * @param {function} fn 函数
 * @param {number} t 等待时间(毫秒)
 * @return {function}
 */
function debounce(fn, t = 500) {
  return XEUtils.debounce(fn, t, {
    leading: true,
    trailing: false
  })
}

/**
 * 函数防抖 inputDebounce
 * @param {function} fn 函数
 * @param {number} t 等待时间(毫秒)
 * @return {function}
 */
function inputDebounce(fn, t = 500) {
  return XEUtils.debounce(fn, t, {
    leading: true
  })
}

/**
 * 函数节流
 * @param {function} fn 函数
 * @param {number} t 间隔时间(毫秒)
 * @return {function}
 */
function throttle(fn, t) {
  let timeId
  let firstTime = true
  const interval = t || 500
  return function () {
    const args = arguments
    if (firstTime) {
      fn.apply(this, args)
      firstTime = false
      return
    }
    if (timeId) {
      return
    }
    timeId = setTimeout(() => {
      clearTimeout(timeId)
      timeId = null
      fn.apply(this, args)
    }, interval)
  }
}

/**
 * 深克隆
 * @param {object|array} 源数据
 * @return {object|array}
 */
function deepClone(source) {
  return XEUtils.clone(source, true)
}

/**
 * 遍历树的方法
 * @tree {array} 源数据
 */
function filterTree(tree, fn) {
  return XEUtils.filterTree(tree, fn)
}

/**
 * 获取数据类型
 * @param {any} data 数据
 * @return {string} 'array'
 */
function getDataType(data) {
  const str = Object.prototype.toString.call(data)
  return str.match(/\s(\w*)\]/)[1].toLowerCase()
}

/**
 * 对象合并 (对象属性深度合并,其他属性覆盖更新(a覆盖b))
 * @param {object} a 对象
 * @param {object} b 对象
 * @return {object} 合并后的对象 (新)
 */
function objectMerge(a, b) {
  const obj = JSON.parse(JSON.stringify(a))
  return (function merge(target, source) {
    if (typeof target !== 'object') {
      target = {}
    }
    if (Array.isArray(source)) {
      return source.slice()
    }
    Object.keys(source).forEach((property) => {
      const sourceProperty = source[property]
      if (typeof sourceProperty === 'object') {
        target[property] = merge(target[property], sourceProperty)
      } else {
        target[property] = sourceProperty
      }
    })
    return target
  })(obj, b)
}

/**
 * 获取日期范围内的所有日期项
 * @param {string} type 'day'按天 'month'按月
 * @param {array} range 日期范围,第一项为开始日期,第二项为结束日期(可选,不传时默认30天或者12个月)
 * @return {array} 该范围内的所有日期项数组
 */
function getDateRangeItems(type, range) {
  const arr = []
  let start, end, times
  if (type === 'day') {
    // 按天
    if (!range || range.length === 0) {
      start = new Date()
      end = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 29)
    } else {
      start = new Date(range[0])
      end = new Date(range[1])
    }
    times = (end.getFullYear() - start.getFullYear() + 1) * 366
    for (let i = 0; i < times; i++) {
      arr.push(formatDate(start, '{y}-{m}-{d}'))
      if (formatDate(start, '{y}-{m}-{d}') === formatDate(end, '{y}-{m}-{d}')) {
        break
      }
      start.setTime(start.getTime() + 3600 * 1000 * 24)
    }
  } else if (type === 'month') {
    // 按月
    if (!range || range.length === 0) {
      start = new Date()
      end = new Date()
      start.setMonth(start.getMonth() - 11)
    } else {
      start = new Date(range[0])
      end = new Date(range[1])
    }
    times = (end.getFullYear() - start.getFullYear() + 1) * 12
    for (let i = 0; i < times; i++) {
      arr.push(formatDate(start, '{y}-{m}'))
      if (formatDate(start, '{y}-{m}') === formatDate(end, '{y}-{m}')) {
        break
      }
      start.setMonth(start.getMonth() + 1)
    }
  }
  return arr
}

/**
 * 对象数组转换成带有children属性的对象数组
 * @param {array} list 数据源
 * @param {string} pAttr 参照属性名
 * @param {string} cAttr 比较属性名
 * @param {number | string} 参照属性名对应的属性值
 * @return {array}
 */
export function treeData(list, pAttr, cAttr, pAttrVal) {
  const pList = []
  const cList = []
  list.map((val) => {
    if (val[cAttr] !== pAttrVal) {
      cList.push(val)
    } else {
      pList.push({ children: [], ...val })
    }
  })
  pList.map((val, index) => {
    pList[index].children = cList.filter((c) => c[cAttr] === val[pAttr])
  })
  return pList
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值