项目中常用方法汇总

防抖

export function throttle (fn, interval = 500) {
  let canRun = true
  return function () {
    if (!canRun) return
    canRun = false
    setTimeout(() => {
      fn.apply(this, arguments)
      canRun = true
    }, interval)
  }
}

节流

export function debounce (fn, wait = 500, immediate) {
  let timer
  return function () {
    if (immediate) {
      fn.apply(this, arguments)
    }
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, arguments)
    }, wait)
  }
}

获取文件名

export function downloadUrlFile (url, fileName) {
  url = url.replace(/\\/g, '/')
  const xhr = new XMLHttpRequest()
  xhr.open('GET', url, true)
  xhr.responseType = 'blob'
  // xhr.setRequestHeader('Authorization', 'Basic a2VybWl0Omtlcm1pdA==');
  xhr.onload = () => {
    if (xhr.status === 200) {
      // 获取文件blob数据并保存
      saveAs(xhr.response, fileName)
    }
  }
  xhr.send()
}
/**
 * URL方式保存文件到本地
 * @param data 文件的blob数据
 * @param name 文件名
 */
function saveAs (data, name) {
  var urlObject = window.URL || window.webkitURL || window
  var exportBlob = new Blob([data])
  var saveLink = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
  saveLink.href = urlObject.createObjectURL(exportBlob)
  saveLink.download = name
  saveLink.click()
}
 

时间戳简析

export function dateFormat (fmt, date) {
  let ret
  const opt = {
    'Y+': date.getFullYear().toString(), //
    'm+': (date.getMonth() + 1).toString(), //
    'd+': date.getDate().toString(), //
    'H+': date.getHours().toString(), //
    'M+': date.getMinutes().toString(), //
    'S+': date.getSeconds().toString() //
    // 有其他格式化字符需求可以继续添加,必须转化成字符串
  }
  for (const k in opt) {
    ret = new RegExp('(' + k + ')').exec(fmt)
    if (ret) {
      fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0')))
    }
  }
  return fmt
}
阿拉伯数字转换成大写汉字
export function numberParseChina (money) {
  // 汉字的数字
  let cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
  // 基本单位
  let cnIntRadice = ['', '拾', '佰', '仟']
  // 对应整数部分扩展单位
  let cnIntUnits = ['', '万', '亿', '兆']
  // 对应小数部分单位
  let cnDecUnits = ['角', '分', '毫', '厘']
  // 整数金额时后面跟的字符
  let cnInteger = '整'
  // 整型完以后的单位
  let cnIntLast = '圆'
  // 最大处理的数字
  let maxNum = 999999999999999.9999
  // 金额整数部分
  let integerNum
  // 金额小数部分
  let decimalNum
  // 输出的中文金额字符串
  let chineseStr = ''
  // 分离金额后用的数组,预定义
  let parts
  if (money === '') { return '' }
  money = parseFloat(money)
  if (money >= maxNum) {
    // 超出最大处理数字
    return ''
  }
  if (money === 0) {
    chineseStr = cnNums[0] + cnIntLast + cnInteger
    return chineseStr
  }
  // 转换为字符串
  money = money.toString()
  if (money.indexOf('.') === -1) {
    integerNum = money
    decimalNum = ''
  } else {
    parts = money.split('.')
    integerNum = parts[0]
    decimalNum = parts[1].substr(0, 4)
  }
  // 获取整型部分转换
  if (parseInt(integerNum, 10) > 0) {
    let zeroCount = 0
    let IntLen = integerNum.length
    for (let i = 0; i < IntLen; i++) {
      let n = integerNum.substr(i, 1)
      let p = IntLen - i - 1
      let q = p / 4
      let m = p % 4
      if (n === '0') {
        zeroCount++
      } else {
        if (zeroCount > 0) {
          chineseStr += cnNums[0]
        }
        // 归零
        zeroCount = 0
        chineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
      }
      if (m === 0 && zeroCount < 4) {
        chineseStr += cnIntUnits[q]
      }
    }
    chineseStr += cnIntLast
  }
  // 小数部分
  if (decimalNum !== '') {
    let decLen = decimalNum.length
    for (let i = 0; i < decLen; i++) {
      let n = decimalNum.substr(i, 1)
      if (n !== '0') {
        chineseStr += cnNums[Number(n)] + cnDecUnits[i]
      }
    }
  }
  if (chineseStr === '') {
    chineseStr += cnNums[0] + cnIntLast + cnInteger
  } else if (decimalNum === '') {
    chineseStr += cnInteger
  }
  return chineseStr
}

数组去重

export function filterArrayByKey (arr, key) {
  if (!(Array.isArray(arr))) return []
  const hash = {}
  return arr.filter((item) => {
    if (hash[item[key]]) return false
    hash[item[key]] = true
    return true
  })
}
格式化金额数字,第一个参数是数字,第二个是保留几位小数,三位加逗号
export function formatMoney (s, n) {
  if (s) {
    n = n > 0 && n <= 20 ? n : 2
    s = parseFloat((s + '').replace(/[^\d.-]/g, '')).toFixed(n) + ''
    let l = s.split('.')[0].split('').reverse()
    let r = s.split('.')[1]
    let t = ''
    for (let i = 0; i < l.length; i++) {
      t += l[i] + ((i + 1) % 3 === 0 && (i + 1) !== l.length ? ',' : '')
    }
    return t.split('').reverse().join('') + '.' + r
  }
}
清除一个数组中值为空的项
export const cleanEmptyInArray = function (array) {
  let [...newArray] = array
  const count = newArray.length
  for (let i = count - 1; i >= 0; i--) {
    if (newArray[i] === '' || newArray[i] === null || newArray[i] === undefined) {
      newArray.splice(i, 1)
    }
  }
  return newArray
}

基于ekement表格合计方法


    /* 合计方法 */
    Vue.prototype.$calcSummaries = function (columns, data, showCheckBox) {
      const sums = []
      columns.forEach((column, index) => {
        const values = data && data.map(item => Number(item[column.property]))
        // console.log(values)
        if (column.columnKey) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr)
            if (!isNaN(value)) {
              switch (column.columnKey) {
                case 'amount':
                  return (Number(prev) + Number(curr)).toFixed(2)
                case 'number':
                  return (Number(prev) + Number(curr)).toFixed(3)
                case 'int':
                  return (Number(prev) + Number(curr))
                case 'amount0':
                  return (Number(prev) + Number(curr)).toFixed(0)
                default:
                  return (Number(prev) + Number(curr)).toFixed(2)
              }
            } else {
              switch (column.columnKey) {
                case 'amount':
                  return Number(prev).toFixed(2)
                case 'number':
                  return Number(prev).toFixed(3)
                case 'int':
                  return Number(prev)
                default:
                  return Number(prev).toFixed(6)
              }
            }
          }, 0)
        } else {
          sums[index] = ''
        }
      })
      if (showCheckBox) {
        sums[2] = '合计'
      } else {
        sums[1] = '合计'
      }
      return sums
    }

页面内部合计方法
getSummaries (param) {
      const { columns, data } = param
      return this.$calcSummaries(columns, data)
    }
需要合计行加配置项
column-key="amount"

 过滤对象中空值

traverse (data) {
      const keys = Object.keys(this.formData)
      for (let item of keys) {
        if (!this.isDef(this.formData[item])) this.$delete(this.formData, item)
      }
    },
    isDef (v) {
      return v !== undefined && v !== null && v !== ''
    },

 值级map转换

// 付款条款类型
export const PAYMENT_VALUE = new Map([
  ['ADVANCE', '预付款'],
  ['PAY_FOR_RECEIVE', '到货款'],
  ['PAY_FOR_PROGRESS', '进度款'],
  ['FINAL_FEE', '完工款'],
  ['PAY_FOR_ACCEPT', '验收款'],
  ['QUALITY_ASSURANCE', '质保金'],
  ['PERFORMANCE_BOND', '履约保证金'],
  ['GOODS_OFFSET_COST', '以货抵费'],
  ['OTHERS', '其他']
])
getpaymentVal (val) {
      return PAYMENT_VALUE.get(val)
    },
 

 JSON去重

unique (type, arr) { // 根据唯一标识no来对数组进行过滤
      const res = new Map() // 定义常量 res,值为一个Map对象实例
      // 返回arr数组过滤后的结果,结果为一个数组   过滤条件是,如果res中没有某个键,就设置这个键的值为1
      return arr.filter((arr) => !res.has(arr[type]) && res.set(arr[type], 1))
    },

// type 删选条件
// arr 数据源

 

日期格式化方法
/**
 * 日期格式化方法
 * @param {string} date     [可选] 要格式化的时间
 * @param {string} fmt      [可选] 时间格式
 *
 * 月(M)、日(D)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(Q) ==> 可以用 1-2 个占位符
 * 年(Y) ==> 1-4 个占位符
 * 毫秒(S) ==> 1 个占位符(是 1-3 位的数字)
 */
export function formatDate (date = Date.now(), fmt = 'YYYY-MM-DD HH:mm:ss') {
  if (!date) return '-'
  date = new Date(date)
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'D+': date.getDate(), //
    'h+': date.getHours() % 12 || 12, // 12小时
    'H+': date.getHours(), // 24小时
    'm+': date.getMinutes(), // 分钟
    's+': date.getSeconds(), //
    'Q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds() // 毫秒
  }
  const week = {
    0: '\u65e5',
    1: '\u4e00',
    2: '\u4e8c',
    3: '\u4e09',
    4: '\u56db',
    5: '\u4e94',
    6: '\u516d'
  }
  if (/(Y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  }
  if (/(E+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (RegExp.$1.length > 1
        ? RegExp.$1.length > 2
          ? '\u661f\u671f'
          : '\u5468'
        : '') + week[date.getDay() + '']
    )
  }
  Object.keys(o).forEach(k => {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
    }
  })
  return fmt
}
/**
 * 获取格式化分时秒钟的毫秒数
 *
 * @param {string} time 根据分时秒格式(如: 12:11.300),获取毫秒
 * @return {Number}
 */
export function getMilliseconds (time) {
  const reg = /(\d+):(\d+)(\.(\d+))*/g
  const ret = reg.exec(time)

  if (!ret) {
    return 0
  }

  const min = ret[1] || 0
  const sec = ret[2] || 0
  const mil = ret[4] || 0

  return (
    parseInt(min, 10) * 60 * 1000 + parseInt(sec, 10) * 1000 + parseInt(mil, 10)
  )
}

/**
 * 获取格式化分时秒钟的总秒数
 *
 * @param {string} time 根据分时秒格式(如: 12:11.300),获取秒
 * @return {Number}
 */
export function getSeconds (time) {
  const mil = getMilliseconds(time)

  return mil / 1000
}
 

 项目过滤器

import Vue from 'vue'
import _lo from 'lodash'
import { formatDate } from '@/util/datetime'
import { numberFormat } from '@/util/utils'

const filters = {
  /**
   * 数据特殊处理
   * val: 要转换的数据
   * format: 数据转换格式,是个对象,type指定要转换的类型(目前有map),其他的属性则是特殊类型的数据处理。
   * 如:format: { type: 'map', statusMap: { 0: '已启用', 1: '已停用'}}
   *    format: { type: 'rate'}
   *    format: { type: 'date', fmt: 'YYYY-MM-DD'}
   *  总之,format对象传入要处理的数据类型和要转换的特殊的参数,目前type只有三种类型,有需要的可自行添加。
   */
  getScope: (val, format = { type: '' }, otherData) => {
    if (typeof val === 'undefined' || val === null || val === '') return '-' // 非空判断
    if (!(val || format.type)) return '-'
    switch (format.type) {
      case 'map':
        return format.statusMap[val] || '-'
      case 'reserveZeroMap':
        return format.statusMap[val] ?? '-'
      case 'reserveZero':
        return val ?? '-'
      case 'join':
        let res = val.map((item) => item.valueName).join('')
        return res || '-'
      case 'mapPost':
        return format.statusMap[val] || val
      case 'rate':
        return val + '%'
      case 'fn':
        return format.fn(val, otherData)
      case 'date':
        return formatDate(val, format.fmt)
      case 'price':
        return numberFormat(val, format.digit || 2, '.', ',', 'round')
      case 'number':
        // 对 NAN 数据进行过滤
        if (Number.isNaN(val)) val = 0
        return _lo.round(+val, 3).toFixed(3)
      case 'total':
        return '共计' + val
      case 'shipAddress':
        if (otherData.transportMode === '3') {
          return '-'
        } else {
          return val
        }
      case 'isHas':
        return val ? '' : ''
      default:
        return val || '-'
    }
  }
}

Object.keys(filters).forEach(key => Vue.filter(key, filters[key]))
// * 验证金额以100,000.00的方式
// * @param {*} number 要格式化的数字
// * @param {*} decimals 保留几位小数
// * @param {*} decPoint 小数点符号
// * @param {*} thousandsSep 千分位符号
// * @param {*} roundtag 舍入参数,默认 'ceil' 向上取,'floor'向下取,'round' 四舍五入
export function numberFormat (number, decimals, decPoint, thousandsSep, roundtag) {
  number = (number + '').replace(/[^0-9+-Ee.]/g, '')
  roundtag = roundtag || 'ceil' // 'ceil','floor','round'
  var n = !isFinite(+number) ? 0 : +number
  var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
  var sep = (!thousandsSep) ? ',' : thousandsSep
  var dec = (typeof decPoint === 'undefined') ? '.' : decPoint
  var s = ''
  var toFixedFix = function (n, prec) {
    var k = Math.pow(10, prec)
    return '' + parseFloat(Math[roundtag](parseFloat((n * k).toFixed(prec * 2))).toFixed(prec * 2)) / k
  }
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
  var re = /(-?\d+)(\d{3})/
  while (re.test(s[0])) {
    s[0] = s[0].replace(re, '$1' + sep + '$2')
  }
  if ((s[1] || '').length < prec) {
    s[1] = s[1] || ''
    s[1] += new Array(prec - s[1].length + 1).join('0')
  }
  return s.join(dec)
}

基于ele 输入格式验证input

<template>
  <el-input v-bind="$attrs" v-bind:value="value" v-on="inputListeners">
    <template slot="append">
      <slot name="append"></slot>
    </template>
    <template slot="prepend">
      <slot name="prepend"></slot>
    </template>
    <template slot="prefix">
      <slot name="prefix"></slot>
    </template>
    <template slot="suffix">
      <slot name="suffix"></slot>
    </template>
  </el-input>
</template>

<script>

/**
 * @Description: input 全局注册组件,新增 mode 和 pattern 属性 (二 选 一)
 * @Description: mode 是定义好的一些 固定模式,可扩展
 * @Description: pattern 是正则表达式,自定义程度高
 * @Description: 所有 el-input 官方属性都可继承
 * @use:
 * <vd-el-input
 *  v-model="xxxx"
 *  placeholder="请输入"
 *  mode="thereDecimal"
 *  clearable></vd-el-input>
 * @author Miracle TJF
 * @date 2020/4/10
*/
export default {
  name: 'VdInput',
  inheritAttrs: false,
  props: {
    value: {
      type: [String, Number],
      default: ''
    },
    mode: {
      type: String,
      default: ''
    },
    pattern: {
      type: RegExp,
      default () {
        return /.*/
      }
    }
  },
  computed: {
    inputListeners: function () {
      let vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
        // 我们从父级添加所有的监听器
        this.$listeners,
        // 然后我们添加自定义监听器,
        // 或覆写一些监听器的行为
        {
          // 这里确保组件配合 `v-model` 的工作
          input: function (val) {
            vm.interceptValue(val)
          }
        }
      )
    }
  },
  created () {
    this.initProps()
  },
  data () {
    return {
      currentPattern: this.pattern
    }
  },
  methods: {
    initProps () {
      if (this.mode && modeMap[this.mode]) {
        this.currentPattern = modeMap[this.mode]
      }
    },
    interceptValue (val) {
      if (!val) {
        return this.$emit('input', '')
      }
      const reg = this.generateReg()
      const match = val.match(reg)
      if (match && match[1]) {
        this.$emit('input', match[1])
      }
    },
    generateReg () {
      const source = this.currentPattern.source
      const flags = this.currentPattern.flags
      return new RegExp(`(${source})`, flags)
    }
  }
}

// 预置格式 (需要额外的可自行完善,注释要写清楚)
const modeMap = {
  int: /\d+/, // 整数
  twoDecimal: /([1-9]\d*|0)(\.\d{0,2})?/, // 两位小数
  threeDecimal: /([1-9]\d*|0)(\.\d{0,3})?/, // 三位小数
  threeIntegerTwoDecimal: /([1-9]\d{0,2}|0)(\.\d{0,2})?/, // 最多三位整数,最多两位小数
  thereDecimal: /\d+(\.\d{0,3})?/, // 三位小数
  twoNotEqualDecimal: /^([1-9][0-9]*)+(\.\d{0,2})?/, // 大于0两位小数
  natThereDecimal: /^-?\d+(\.\d{0,3})?/, // 正负三位小数
  sixeDecimal: /\d{0,9}(\.\d{0,6})?/, // 小数点前九后六
  eightDecimal: /\d{0,8}(\.\d{0,2})?/, // 小数点前八后二
  thirteenDecimal: /\d{0,13}(\.\d{0,2})?/, // 小数点前十八后二
  tenAndTwo: /([1-9]\d{0,9}|0)(\.\d{0,2})?/, // 前十后二
  canZeroInt: /^(0|[1-9][0-9]*)$/, // 只能输入0或者非0开头的数字
  volumeDecimal: /^[0-9](\.\d{0,2})?$|^([1-3][0-9]{2}|[1-9][0-9]{0,1})(\.\d{0,2})?$|^400/ // 大于0小于等于400两位小数
}
</script>
// 挂载全局
import Vue from 'vue'
// 输入框组件封装
import VdElInput from '@/components/globals/VdElInput'

Vue.component('vd-el-input', VdElInput)
// 使用
<vd-el-input
                v-model.trim="scope.row.amountRate"
                type="text"
                placeholder="请输入"
                style="width:100%"
                :maxlength="6"
                clearable
                mode="twoNotEqualDecimal"
              ></vd-el-input>

 递归查找

function getGroupName(data, id) {
    let a
    if (!data) {
        return
    }
    for (let i = 0; i < data.length; i++) {
        const item = data[i]
        // console.log(item)
        if (item.categoryCode === id) {
            a = item.categoryFullName
            return a
        } else if (item.children && item.children.length > 0) {
            if (getGroupName(item.children, id)) {
                return a = getGroupName(item.children, id)
            }
        }
    }
    return a
}
let str = getGroupName(array, 8)
console.log('str', str)

 

posted @ 2020-05-25 14:59  Followme789  阅读(227)  评论(0编辑  收藏  举报