开发常用方法记录

目录

获取数据类型

深拷贝

格式化金额

图片压缩

获取随机16进制颜色

节流,防抖函数

证件号脱敏

uniapp小程序开发u-toast封装

获取身份证有效期限

 文件下载

银行卡手机号添加空格

地球坐标转高德坐标

div获取焦点和失去焦点问题


获取数据类型

    getType() {
      var obj = Array.prototype.shift.apply(arguments);
      var toString = Object.prototype.toString;
      var map = {
        "[object Boolean]": "boolean",
        "[object Number]": "number",
        "[object String]": "string",
        "[object Function]": "function",
        "[object Array]": "array",
        "[object Date]": "date",
        "[object RegExp]": "regExp",
        "[object Undefined]": "undefined",
        "[object Null]": "null",
        "[object Map]": "map",
        "[object Object]": "object"
      };
      if (obj instanceof Element) {
        return "element";
      }
      return map[toString.call(obj)];
    },

    // 调用
    var type = this.getType(data);

深拷贝

deepClone() {
      var data = Array.prototype.shift.apply(arguments);
      var type = this.getType(data);
      var obj;
      if (type === "array") {
        obj = [];
        for (var i = 0, len = data.length; i < len; i++) {
          obj.push(this.deepClone(data[i]));
        }
      } else if (type === "object") {
        obj = {};
        for (var key in data) {
          obj[key] = this.deepClone(data[key]);
        }
      } else if (type === "map") {
        obj = new Map();
        data.forEach((item, key) => {
          obj.set(key, this.deepClone(item));
        });
      } else {
        return data;
      }
      return obj;
    },

格式化金额

/**
 * 格式化金额
 * 1000 => '1000.00'
 */
export const moneyFormat = x => {
  let f = parseFloat(x)
  if (isNaN(f)) {
    return 0.0
  }
  f = Math.round(x * 100) / 100
  let s = f.toString()
  let rs = s.indexOf('.')
  if (rs < 0) {
    rs = s.length
    s += '.'
  }
  while (s.length <= rs + 2) {
    s += '0'
  }
  return s
}

/**
 * 10000 => "10,000"
 */
export const toThousandFilter = num => {
  return (+num || 0)
    .toString()
    .replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}
/**
 * 大数值转换为万,亿函数
 *
 * @param {Number} 大数
 * @param {Number} 保留几位小数
 */
export const numConversion = (num, point = 2) => {
  const numStr = num.toString().split('.')[0] // 去掉小数点后的数值字符串
  const numLen = numStr.length
  if (numLen < 6) {
    return numStr
  } else if (numLen >= 6 && numLen <= 8) {
    const decimal = numStr.substring(numLen - 4, numLen - 4 + point)
    const res = parseInt(num / 10000) + '.' + decimal + '万'
    return res
  } else if (numLen > 8) {
    const decimal = numStr.substring(numLen - 8, numLen - 8 + point)
    const res = parseInt(num / 100000000) + '.' + decimal + '亿'
    return res
  }
}

/**
 * 大金额转换
 * @param {*} money 金额
 * @returns 
 */
export function formatMoney (money) {
    if (money !== undefined && money !== null && money !== ''){
        let s
        let m = parseFloat(money);
        if (m < 10000){
            s = '元';
        } else if (m >= 10000 && m < 100000000){
            s = '万元';
            m = m / 10000;
        } else {
            s = '亿';
            m = m / 100000000;
        }
        let result = m.toFixed(`${m}`.includes('.') ? 2 : 0) + s;
        return result;
    } else {
        return '/';
    }
}

图片压缩

需安装 lrz:npm i lrz

import lrz from 'lrz'

/**
 * 图片压缩
 *
 * @export
 * @param {*} file 通过 input:file 得到的文件,或者直接传入图片路径
 * @param {number} [width=1200] 图片最大不超过的宽度,默认为1200
 * @param {number} [height=1200] 同上
 * @param {number} [quality=0.7] 图片压缩质量,取值 0 - 1,默认为0.7
 * @returns 返回值是一个promise对象
 * rst.formData 后端可处理的数据
 * rst.file 压缩后的file对象(默认已经丢在rst.formData有一份了),需要注意的是如果压缩率太低的话,这个会是原始的file对象
 * rst.fileLen 生成后的图片的大小,后端可以通过此值来校验是否传输完整
 * rst.base64 生成后的图片base64,后端可以处理此字符串为图片,也直接用于img.src = base64
 * rst.base64Len 生成后的base64的大小,后端可以通过此值来校验是否传输完整 (如果采用base64上传方式)
 * rst.origin 也就是原始的file对象,里面存了一些原始文件的信息,例如大小,日期等。
 *
 */
export default async function compress(file, width = 1200, height = 1200, quality = 0.7) {
  return await lrz(file, { width, height, quality })
}

获取随机16进制颜色

/**
 * 随机16进制颜色 hexColor
 * return  string str 带#号的随机16进制颜色
 */
export const hexColor = () => {
  let str = '#'
  const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']
  for (let i = 0; i < 6; i++) {
    const index = Number.parseInt(Math.random() * 16)
    str += arr[index]
  }
  return str
}

节流,防抖函数

/**
 * 节流,当持续触发事件时,在规定时间段内只能调用一次回调函数。
 * 用Vue.prototype.$deb=Debounce;   这种方式做导入时 只能导入一个
 */
export const Throttle = (fn, interval = 500) => {
  let last
  let timer
  return function() {
    const th = this
    const args = arguments
    const now = +new Date()
    if (last && now - last < interval) {
      clearTimeout(timer)
      timer = setTimeout(function() {
        last = now
        fn.apply(th, args)
      }, interval)
    } else {
      last = now
      fn.apply(th, args)
    }
  }
}
/**
 * 防抖,指触发事件后在规定时间内回调函数只能执行一次,
 * 如果在规定时间内又触发了该事件,则会重新开始算规定时间
 */
export default function Debounce(fn,delay = 500) {
  let timer
  return function() {
    
    const th = this
    const args = arguments
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(function() {
      timer = null
      fn.apply(th, args)
    }, delay)
  }
}

证件号脱敏

export const stringEncrypt = (str) => {
  if (!str) return
  const len = str.length
  if (len < 8) return str
  const center = str.slice(4, len - 4)
  const b = center.replace(/\w/gi, '*')
  str = str.slice(0, 4) + b + str.slice(len - 4, len)
  return str
}

uniapp小程序开发u-toast封装

export const uUnits= {
  uToast({ refs, msg, zIndex = 10079}) {
    let platForm = ""
    // #ifdef H5
    platForm = "H5"
    // #endif
    let tipRef = null
    if (platForm === 'H5') {
      tipRef = this.$refs[refs]
    } else {
      tipRef = this.$children.find(item => item.$options.name === 'u-toast')
    }
    tipRef.show({
      message: msg || '',
      duration: 2000,
      zIndex: zIndex
    })
  }
}
// 调用
uUnits.uToast.call(this, {
	refs: 'tipRef',
	msg: '报名成功',
})

获取身份证有效期限

/**
 * 计算身份证有效期限
 * @param {*} idCardNo 身份证号
 * @param {*} startTime 身份证有效期开始日期
 */
function getRightSpanTime(idCardNo,startTime) {
	let valid = 5;
	const year = +idCardNo.substring(6, 10);
	const month = +idCardNo.substring(10,12);
	const day = +idCardNo.substring(12,14);
	// 领证年份
	const getLiceDate = new Date(startTime.replace(/-/g,'/'));
	const getLiceYear = getLiceDate.getFullYear();
	const getLiceMonth = getLiceDate.getMonth() + 1;
	const getLiceDay = getLiceDate.getDate();
	// 领证年龄(领证年龄取整岁)
	let getLicenseAge = getLiceYear - year;
	if(getLiceMonth < month) {
		getLicenseAge--
	} else if(getLiceMonth === month) {
		if(getLiceDay < day) {
			getLicenseAge--
		}
	}
	/* 年龄小于16,有效期5年
    年龄大于等于16,小于等于25,有效期10年
    年龄大于等于26,小于等于45,有效期20年
    年龄大于等于46,长期 */
	if(getLicenseAge < 0) {
		valid = 0;
	} else if(getLicenseAge < 16) {
		valid = 5;
	} else if(getLicenseAge >= 16 && getLicenseAge <=25) {
		valid = 10;
	} else if(getLicenseAge >= 26 && getLicenseAge <= 45) {
		valid = 20;
	} else {
		// 长期
		valid = 21
	}
	return valid
}


// 获取身份证表单起止时间间隔
function getIDFormTimeSpan(startTime,endTime) {
	let year;
	const sTime = startTime.replace(/-/g,'/');
	const eTime = endTime.replace(/-/g,'/');
	let sYear = new Date(sTime).getFullYear();
	let eYear = new Date(eTime).getFullYear();
	let sMonth = new Date(sTime).getMonth() + 1;
	let eMonth = new Date(eTime).getMonth() + 1;
	let sDay = new Date(sTime).getDate();
	let eDay = new Date(eTime).getDate();
	year = eYear - sYear;
	// 计算年间距后,保证月份日期相等
	const IsEquel = sMonth === eMonth && sDay === eDay;
	return {year,IsEquel}
}

 文件下载

/**
 * 下载文件
 * @param res 必传,服务端返回的响应
 * @param fileName 生成文件名称,可不传,使用响应头content-disposition设置
 * @param type 文件媒体类型,可匹配默认值,也可传其他值
 */
export const downloadFile = function({ res, fileName, type }) {
  // find more in https://www.iana.org/assignments/media-types/media-types.xhtml
  const mimeTypeMap = {
    doc: 'application/msword',
    pdf: 'application/pdf',
    excel: 'application/vnd.ms-excel'
  }

  let name = fileName
  const contentDisposition = res.response.headers['content-disposition']
  if (!fileName && contentDisposition) {
    name = decodeURIComponent(contentDisposition.replace(/attachment;\s?filename=/g, ''))
  }

  const typeVale = mimeTypeMap[type] || type
  const blob = new Blob([res], { typeVale })

  if ('download' in document.createElement('a')) {
    const link = document.createElement('a')
    link.download = name
    link.style.display = 'none'
    link.href = URL.createObjectURL(blob)
    document.body.appendChild(link)
    link.click()
    URL.revokeObjectURL(link.href)
    document.body.removeChild(link)
  } else {
    navigator.msSaveBlob(blob, name)
  }
}

银行卡手机号添加空格

// 银行卡号
// 添加空格
card.replace(/\s/g, '').replace(/[^\d]/g, '').replace(/(\d{4})(?=\d)/g, '$1 ');
// 取消空格
card.replace(/[, ]/g,'')

// 手机号
// 添加空格
phone.replace(/\D/g,'').replace(/^/,'$& ').replace(/....(?!$)/g,'$& ')

地球坐标转高德坐标

const PI = 3.1415926535897932384626;
const a = 6378245.0;
const ee = 0.00669342162296594323;

function transformLat(lng, lat) {
  let ret =
    -100.0 +
    2.0 * lng +
    3.0 * lat +
    0.2 * lat * lat +
    0.1 * lng * lat +
    0.2 * Math.sqrt(Math.abs(lng));
  ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
  ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0;
  ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0;
  return ret;
}
function transformLng(lng, lat) {
  let ret =
    300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0;
  ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0;
  ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0;
  return ret;
}

function outOfChina(lng, lat) {
  return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271 || false;
}

export default function (lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  } else {
    let dlat = transformLat(lng - 105.0, lat - 35.0);
    let dlng = transformLng(lng - 105.0, lat - 35.0);
    const radlat = (lat / 180.0) * PI;
    let magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    const sqrtmagic = Math.sqrt(magic);
    dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
    dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
    const mglat = lat + dlat;
    const mglng = lng + dlng;
    return [+mglng.toFixed(6), +mglat.toFixed(6)];
  }
}

// 使用
import wgs84ToGCJ02 from '/@/utils/map/wgs84ToGCJ02';
const [longitude, latitude] = wgs84ToGCJ02(+item.longitude, +item.latitude);

div获取焦点和失去焦点问题

默认情况下 div 标签是没有获得焦点 focus() 和失去焦点 blur() 事件的。

如果想要 div 可以拥有这两个事件,可以给 div 标签加上 tabindex="-1" 属性,如下:

<div tabindex="-1">...</div>

这样就可以给 div 加上焦点事件了。

同理,利用tabindex="-1" 也可以给其他不支持焦点事件的标签添加焦点事件。

猜你喜欢

转载自blog.csdn.net/lwx931449660/article/details/115190770