虫虫JavaScript相关文章

封装项目中常用的工具函数

2019-09-30  本文已影响0人  Issho

☼ 注:笔者是一名卑微的小前端,文章是根据自己当前项目做的笔记,具体应用请参照自己实际项目情况

1、cookie操作
import cookie from 'cookie'

// 增加时间秒数
export function dateAddSeconds(sec) {
    return new Date((new Date()).getTime() + (sec * 1000))
}

export class Cookie {
    static setCookie(name, val, option) {
        const v = (typeof val === 'string') ? val : JSON.stringify(val)
        document.cookie = cookie.serialize(name, v, option)
    }

    static setCookieExpireInSecond(name, val, second, option) {
        Cookie.setCookie(name, val, { expires: dateAddSeconds(second), ...option })
    }

    static getCookie(cName) {
        const p = cookie.parse(document.cookie)
        if (cName in p) {
            return p[cName]
        }
        return null
    }

    static getJSONCookie(cName) {
        return JSON.parse(Cookie.getCookie(cName))
    }

    static deleteCookie(cName) {
        Cookie.setCookie(cName, '', { maxAge: -1 })
    }

}
2、本地存储
import { Cookie } from './cookie'

const PREFIX = 'cache_'

export default class Cache {
    static getItem(k) {
        try {
            return JSON.parse(localStorage.getItem(PREFIX + k))
        } catch (e) {
            return undefined
        }
    }

    static setItem(k, v) {
        const d = typeof v === 'string' ? v : JSON.stringify(v)
        localStorage.setItem(PREFIX + k, d)
    }

    static removeItem(k) {
        localStorage.removeItem(PREFIX + k)
    }

    static clear() {
        Object.keys(localStorage).filter(i => i.startsWith(PREFIX)).forEach(j => localStorage.removeItem(j))
    }

    // 用户信息及登录状态
    static getUserInfo() {
        const userData = Cookie.getCookie(`${PREFIX}userData`)
        try {
            return JSON.parse(userData)
        } catch (e) {
            return {}
        }
    }

    static setUserInfo(v) {
        Cookie.setCookie('isLogin', '0')
        const d = typeof v === 'string' ? v : JSON.stringify(v)
        Cookie.setCookie(`${PREFIX}userData`, d)
    }

    static clearUserInfo() {
        Cookie.setCookie('isLogin', '-1')
        Cookie.deleteCookie('isLogin')
        Cookie.deleteCookie(`${PREFIX}userData`)
    }
}
3、表单验证
// 表单验证
const regs = {
    number: /^[0-9]*$/,
    integer: /^[+]{0,1}(\d+)$/,
    figure: /^([1-9]\d*|0)(\.\d{1,2})?$/,
    char: /^[A-Za-z]+$/,
    bigChar: /[A-Z]/,
    chinese: /^[\u4e00-\u9fa5]+$/gi,
    anyChinese: /[\u4E00-\u9FA5\uF900-\uFA2D]/,
    mobile: /^1[3456789]{1}[0-9]{9}$/,
    phone: /^([+][0-9]{2,3}[-])?(\(\d{3,4}\)|\d{3,4}-|\s)?\d{6,8}$/,
    numChar: /^[A-Za-z0-9]+$/,
    blankSpace: /\s/,
    email: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/,
    password: /^[0-9A-Za-z]{6,20}$/,
    image: /^image\/(png|jpe?g|gif)$/,
    license: /(^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4}))$)|(^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$)/,
    filepack: /^(.*zip.*)$/,
}

export default class CheckForm {
    // 验证非空
    static notEmpty(str) {
        return (typeof str !== 'undefined' && String(str).trim() !== '' && str !== null)
    }

    // 限制长度
    static lengthLimit(str, minLen, maxLen) {
        let len = 0
        const strLen = str.length
        for (let i = 0; i < strLen; i += 1) {
            if (str[i].match(/[^x00-xff]/ig) !== null) {
                len += 2
            } else {
                len += 1
            }
        }
        if (!maxLen) return len >= minLen
        return (len >= minLen && len <= maxLen)
    }

    // 包含空格
    static hasBlankSpace(str) {
        return regs.blankSpace.test(str)
    }

    /** 基本格式验证 */


    // 验证数字 (包含0开头)
    static isNumber(str) {
        return regs.number.test(str)
    }

    // 验证正整数 (包括0)
    static isInteger(str) {
        return regs.integer.test(str)
    }

    // 验证正整数和小数
    static isFigure(str) {
        return regs.figure.test(str)
    }

    // 验证字母
    static isChar(str) {
        return regs.char.test(str)
    }

    // 验证所有为汉字
    static isChinese(str) {
        return regs.chinese.test(str)
    }

    // 验证有汉字
    static isAnyChinese(str) {
        return regs.anyChinese.test(str)
    }

    // 验证邮件格式
    static isEmail(str) {
        return regs.email.test(str)
    }

    // 验证手机号码格式
    static isMobile(str) {
        return regs.mobile.test(str)
    }

    // 验证电话号码
    static isPhone(str) {
        return regs.phone.test(str)
    }

    // 密码校验
    static isPassword(str) {
        return regs.password.test(str)
    }

    // 验证身份证号码
    static isIdCard(idCardNo) {
        return idCardNo && (/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(idCardNo))
    }

    //验证上传图片的类型
    static isImage(str) {
        return str && regs.image.test(str)
    }

    // 验证车牌号
    static isLicense(str) {
        return regs.license.test(str)
    }

    //验证rar zip压缩包
    static isFilepackage(str) {
        return str && regs.filepack.test(str)
    }
}
4、时间格式化
export function dateFormat(date, format) {
    if (!date) {
        // alert('请传入需要格式化时间参数!');
        return ''
    }
  
    let da = date
    if (typeof date === 'string') da = date.replace(/-/g, '/')
  
    const d = new Date(da)
  
    if (!d.getDate() || isNaN(d.getDate())) {
        // alert('时间格式错误!');
        return ''
    }
  
    const dict = {
        yyyy: d.getFullYear(),
        M: d.getMonth() + 1,
        d: d.getDate(),
        H: d.getHours(),
        m: d.getMinutes(),
        s: d.getSeconds(),
        MM: (`${d.getMonth() + 101}`).substr(1),
        dd: (`${d.getDate() + 100}`).substr(1),
        HH: (`${d.getHours() + 100}`).substr(1),
        mm: (`${d.getMinutes() + 100}`).substr(1),
        ss: (`${d.getSeconds() + 100}`).substr(1),
    }
    try {
        return format.replace(/(yyyy|MM?|dd?|HH?|mm?|ss?)/g, f => dict[f])
    } catch (e) {
        return d
    }
}

// 字符串转时间戳
export function timestamp(time) {
    return Date.parse(new Date(time)) / 1000
}
  
const checkNum = (n, min, max) => (n > min && n < max)
  
const defaultTimeOptions = {
    isCtrYear: false,
    isCtrMonth: false,
    isCtrDay: false,
    isCtrHours: false,
    isCtrMinutes: false,
    isCtrSeconds: false,
    isShowHalfHours: false,
    isShowHalfMinutes: false,
    dateFormatText: 'yyyy-MM-dd T HH:mm:ss',
    beforeText: '前',
    yearText: '年',
    monthText: '月',
    dayText: '天',
    hoursText: '小时',
    minutesText: '分钟',
    secondsText: '秒',
    justNowText: '刚刚',
    maxYearNum: 0,
    maxMonthNum: 12,
    maxDayNum: 30,
    maxHoursNum: 24,
    maxMinutesNum: 60,
    maxSecondsNum: 60,
}
  
export function getTimeBeforeNow(date, opt) {
    if (!date) {
        alert('请输入时间!')
        return null
    }

    // debugger
    const d = dateFormat(date)
    const now = new Date()
    const sInterval = parseInt((now.getTime() - d.getTime()) / 1000, 10)
    const mInterval = parseInt(sInterval / 60, 10)
    const hInterval = parseInt(mInterval / 60, 10)

    const {
        beforeText, justNowText, isShowHalfMinutes, isShowHalfHours,
        isCtrYear, isCtrMonth, isCtrDay, isCtrHours, isCtrMinutes, isCtrSeconds,
        yearText, monthText, dayText, hoursText, minutesText, secondsText,
        maxYearNum, maxMonthNum, maxDayNum, maxHoursNum, maxMinutesNum, maxSecondsNum,
    } = { ...defaultTimeOptions, ...opt }

    if (isCtrYear && (now.getYear() - d.getYear()) <= maxYearNum) {
        return `${now.getYear() - d.getYear()}${yearText}${beforeText}`
    }
    if (isCtrMonth && (now.getMonth() - d.getMonth()) <= maxMonthNum) {
        return `${now.getMonth() - d.getMonth()}${monthText}${beforeText}`
    }
    if (isCtrDay && (now.getDay() - d.getDay()) <= maxDayNum) {
        return `${now.getDay() - d.getDay()}${dayText}${beforeText}`
    }
    if (isCtrHours && checkNum(hInterval, 1, maxHoursNum)) {
        return `${hInterval}${hoursText}${beforeText}`
    }
    if (isCtrMinutes && checkNum(mInterval, 1, maxMinutesNum)) {
        if (isShowHalfHours && mInterval === 30) {
            return `半${hoursText}${beforeText}`
        }
        return `${mInterval}${minutesText}${beforeText}`
    }
    if (isCtrSeconds && checkNum(sInterval, 1, maxSecondsNum)) {
        if (isShowHalfMinutes && sInterval === 30) {
            return `半${minutesText}${beforeText}`
        }
        return `${sInterval}${secondsText}${beforeText}`
    }
    if (isCtrSeconds && sInterval <= 1) {
        return `${justNowText}`
    }

    return dateFormat(d, opt.dateFormatText)
}
  
// 日期处理
export class DateExtend {
    static getNow(dateType) {
        const now = new Date()
        return dateFormat(now, dateType)
    }

    static getNowWeekNumber() {
        const week = new Date().getDay()
        let nowWeek = week
        if (week === 0) nowWeek = 7
        return nowWeek
    }

    static getOneDayWeekWithDateObject(deltaDay = 0, dateType, weekType = [1, 2, 3, 4, 5, 6, 7]) {
        const oneDayLong = 24 * 60 * 60 * 1000
        const now = new Date()
        const dayTime = now.getTime() + (deltaDay * oneDayLong)
        const day = new Date(dayTime)
        const weekDay = now.getDay() + deltaDay
        const week = weekDay > 0 ? weekDay % 7 : 7 + (weekDay % 7)
        return {
            date: dateFormat(day, dateType),
            week: week === 0 ? weekType[6] : weekType[week - 1],
        }
    }

    static getThisWeek(start, dateType, weekType) {
        const today = new Date().getDay()
        const weekArray = [0, 1, 2, 3, 4, 5, 6]
        return weekArray.reduce((prev, next) => {
            prev.push(DateExtend.getOneDayWeekWithDateObject((next + start) - today, dateType, weekType))
            return prev
        }, [])
    }

    static getThisWeekStartMondayArray(dateType, weekType) {
        return DateExtend.getThisWeek(1, dateType, weekType)
    }

    static getThisWeekStartSundayArray(dateType, weekType) {
        return DateExtend.getThisWeek(0, dateType, weekType)
    }
}

export function timeStampConvert(dateString) {
    const d = Date(parseInt(dateString, 10) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' ')
    return new Date(d.replace(/-/g, '/'))
}

// 时间戳转换
export function dateConvert(dateString, split) {
    const dt = timeStampConvert(dateString)
    return `${dt.getFullYear()}${split}${dt.getMonth() + 1}${split}${dt.getDate()}`
}

// 计算两个日期之间的天数
export function getDateDay(date) {
    const now = new Date()
    return parseInt(Math.abs(now - date) / 1000 / 60 / 60 / 24, 10)
}

export function changeDataToNotice(date) {
    if (!date) {
        return ''
    }
    const newDate = new Date(date)
    return `${(newDate.getMonth() + 1)}月${newDate.getUTCDate()}日 ${newDate.getHours()}:${newDate.getMinutes()}`
}

export function minuteHourMinute(minutes) {
    return `${Math.floor(minutes/60)}小时${minutes%60}分`
}

/**
 * Date对象转字符串
 * @param {Date} date Date实例化对象
 * @param {String} type 时间格式
 */
export const formatDate = (date, type) => {

    let [ year, month, day ] = date.toLocaleDateString().split('/').map(item => zerofill(item))

    let [ hour, min, sec ] = [date.getHours(), date.getMinutes(), date.getSeconds()].map(item => zerofill(item))

    let week = weeks[date.getDay()]

    switch (type) {
        case 'YYYY-MM-DD':
            return year + '-' + month + '-' + day
        
        case 'MM-DD':
            return month + '-' + day

        case 'MM-DD hh:mm:ss':
            return month + '-' + day + ' ' + hour + ':' + min + ':' + sec

        case 'YYYY-MM-DD hh:mm:ss':
            return year + '-' + month + '-' + day + ' ' + hour + ':' + min + ':' + sec

        case 'YYYY年MM月DD日':
            return year + '年' + month + '月' + day + '日'

        case 'MM月DD日 W':
            return month + '月' + day + '日' + ' 周' + week

        case 'YYYY年MM月DD日 hh:mm:ss':
            return year + '年' + month + '月' + day + '日' + ' ' + hour + ':' + min + ':' + sec

        case 'YYYY年MM月DD日 hh:mm:ss W':
            return year + '年' + month + '月' + day + '日' + ' ' + hour + ':' + min + ':' + sec + ' 星期' + week
        case 'hh:mm:ss':
            return hour + ':' + min + ':' + sec
    }
}

const weeks = ['日', '一', '二', '三', '四', '五', '六']

const zerofill = n => { return String(n).padStart(2, '0') }

/**
 * 比较日期先后
 * @param {String} d1 日期
 * @param {String} d2 日期
 * @param {String} o 运算符
 * @return true/false
 */
export const compareDate = (d1, d2, o) => {
    const format = d => new Date(d.replace(/-/g, '\/'))
    switch (o) {
        case 'lt':
            return format(d1) < format(d2)
        case 'gt':
            return format(d1) > format(d2)
        case 'lte':
            return format(d1) <= format(d2)
        case 'gte':
            return format(d1) >= format(d2)
        default:
            break
    }
}

/**
 * 时间加减的方法,以月为单位
 * @param {String} date 当前时间
 * @param {Number} months 月数
 */
export const calDate = (date, months) => {
    let d = new Date(date)
    d.setMonth(d.getMonth() + parseInt(months))
    let month = d.getMonth() + 1
    let day = d.getDate()
    return `${d.getFullYear()}-${month < 10 ? `0${month}` : month}-${day < 10 ? `0${day}` : day}`
}

/**
 * 获取当前农历日期
 * @param {Boolean} withYear 是否显示农历年
 */
export const lunarCalendar = withYear => {
    let D = new Date()
    let yy = D.getFullYear()
    let mm = D.getMonth() + 1
    let dd = D.getDate()
    // let ww = D.getDay()
    // let ss = parseInt(D.getTime() / 1000)
    if (yy < 100) yy = '19' + yy
    return GetLunarDay(yy, mm, dd, withYear)
}

//定义全局变量
let madd = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
let tgString = '甲乙丙丁戊己庚辛壬癸'
let dzString = '子丑寅卯辰巳午未申酉戌亥'
let numString = '一二三四五六七八九十'
let monString = '正二三四五六七八九十冬腊'
// let weekString = '日一二三四五六'
let sx = '鼠牛虎兔龙蛇马羊猴鸡狗猪'
let cYear, cMonth, cDay, TheDate
let CalendarData = new Array(
    0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5, 0x50DA9, 0x5AD, 0x2B6, 0x3126E,
    0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B, 0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5,
    0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6, 0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55,
    0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54, 0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B,
    0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B, 0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96,
    0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B,
    0x60A57, 0x52B, 0xA93, 0x40E95
)

const GetBit = (m, n) => {
    return (m>>n)&1
}

//农历转换
const e2c = (...args) => {
    TheDate= (args.length!=3) ? new Date() : new Date(args[0], args[1], args[2])
    let total, m, n, k
    let isEnd = false
    let tmp = TheDate.getYear()
    if (tmp < 1900) {
        tmp += 1900
    }
    total = (tmp - 1921) * 365 + Math.floor((tmp - 1921) / 4) + madd[TheDate.getMonth()] + TheDate.getDate() - 38
   
    if (TheDate.getYear() % 4 == 0 && TheDate.getMonth() > 1) {
        total++
    }
    for (m=0; ; m++) {
        k = (CalendarData[m] < 0xfff) ? 11 : 12
        for (n = k; n >= 0; n--){
            if (total <= 29 + GetBit(CalendarData[m], n)) {
                isEnd = true
                break
            }
            total = total - 29 - GetBit(CalendarData[m], n)
        }
        if (isEnd) break
    }
    cYear = 1921 + m
    cMonth = k - n + 1
    cDay = total
    if (k == 12) {
        if (cMonth == Math.floor(CalendarData[m] / 0x10000) + 1) {
            cMonth = 1 - cMonth
        }
        if (cMonth > Math.floor(CalendarData[m] / 0x10000) + 1){
            cMonth--
        }
    }
}

const GetcDateString = withYear => {
    let tmp = ''
    if (withYear) {
        tmp += tgString.charAt((cYear - 4) % 10)
        tmp += dzString.charAt((cYear - 4) % 12)
        tmp += '('
        tmp += sx.charAt((cYear - 4) % 12)
        tmp += ')年'
    }
    if (cMonth < 1) {
        tmp += '(闰)'
        tmp += monString.charAt(-cMonth - 1)
    } else {
        tmp += monString.charAt(cMonth - 1)
    }
    tmp += '月'
    tmp += (cDay < 11) ? '初' : ((cDay < 20) ? '十' : ((cDay < 30) ? '廿' : '三十'))
    if (cDay % 10 != 0 || cDay == 10) {
        tmp += numString.charAt((cDay - 1) % 10)
    }
    return tmp
}

const GetLunarDay = (solarYear, solarMonth, solarDay, withYear) => {
    if (solarYear < 1921 || solarYear > 2020) {
        return ''
    } else {
        solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11
        e2c(solarYear, solarMonth, solarDay)
        return GetcDateString(withYear)
    }
}
5、类型参数判断
const toString = Object.prototype.toString

/**
  * 检查给定参数是否为数组
  * 使用Array.isArray()检查某个值是否属于数组
  * Example isArray([10, 1, 5]) -> true
  */
export const isArray = val => !!val && Array.isArray(val)

/**
 * 检查给定的参数是否为布尔元素
 * EXample: isBoolean(null) -> false
 * Example: isBoolean(false) -> true
 */
export const isBoolean = val => typeof val === 'boolean'

/**
 * 检查给定的参数是否为函数
 * Example:isFunction('x) -> false
 * Example: isFunction(x => x) => true
 */
export const isFunction = val => val && typeof val === 'function'

/**
 * 检查给定参数是否为number
 * Example: isNumber('1') -> false
 * Example: isNumber(1) -> true
 */
export const isNumber = val => typeof val === 'number'

/**
 * 检查给定参数是否为字符串
 * Example: isString(10) -> false
 * Example: isString('10') -> true
 */
export const isString = val => typeof val === 'string'

/***
 * 检查给定的参数是否为Symbol
 * Example: isSymbol('x) -> false
 * Example: isSymbol(Symbol('x')) -> true
 */
export const isSymbol = val => typeof val === 'symbol'
6、千位分割符
/**
 * 千位分割符
 * @param {Number} num 进行分割的数字
 */
export const thousandBitSeparator = num => {
    try {
        let res = num.toString().replace(/\d+/, n => { // 先提取整数部分
            return n.replace(/(\d)(?=(\d{3})+$)/g, $1 => {
                return $1 + ','
            })
        })
        return res
    } catch (err) {
        return num
    }
}
7、函数节流
/**
 * 函数节流
 *
 * @param {Function} fn 节流函数
 * @param {Number} interval 节流时间(ms),默认500ms
 * @returns {Function} 新函数
 */
export function throttle(fn, interval = 500) {
    let _self = fn
    let timer //定时器
    let firstTime = true//是否第一次调用
    let begin = new Date()
    return function () {
        let args = arguments
        let _me = this
        let current = new Date()

        //如果第一次执行,不需要延迟
        if (firstTime) {
            _self.apply(_me, args)
            return firstTime = false
        }
        //如果定时器还在,说明上一次调用还没有完成
        if (timer) {
            return false
        }
        if (current - begin >= interval) {
            _self.apply(_me, args)
            begin = current
        } else {
            //延迟1段事件执行
            timer = setTimeout(function () {
                clearTimeout(timer)//清理定时器
                timer = null//闭包内存释放
                // _self.apply(_me, args)//返回的新函数、参数借用源函数执行
            }, interval)
        }

    }
}
8、URL处理
// 获取地址上的所有参数转换为对象
export const getURLParameters = (url = window.location.href) => {
    const params = url.match(/([^?=&]+)(=([^(&|#)]*))/g)
    if (params === null) {
        return {}
    } else {
        return params.reduce(
            (a, v) => {
                a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)
                return a
            }, {}
        )
    }
}

// 把参数对象合并生产url
export function setParamObjToUrl(opt = {}, url = '') {
    if (typeof url !== 'string') return null
    let urlPro = ''
    let urlEnd = ''
    if (url !== '') {
        urlPro = url.startsWith('http') ? '' : 'http://'
        urlEnd = '?'
    }
    const completeUrl = `${urlPro}${url}${urlEnd}`
    const options = Object.keys(opt).reduce((arr, obj) => [...arr, `${obj}=${encodeURIComponent(opt[obj])}`], [])
    return `${completeUrl}${options.join('&')}`
}
9、导出Excel
/**
 * 导出Excel,暂时只适用普通url和bloburl,兼容IE10+
 * @param {a} ele a标签
 * @param {blob/url} data blob对象或普通url
 * @param {string} file 导出的文件名,针对blob有效,普通url无效,需要后台来更改文件名
 */
export const insertComponent = (ele, data, file = '数据统计') => {

    if (!data) {
        return
    }

    // 针对IE
    if (window.navigator.msSaveBlob && typeof data === 'object') {
        return window.navigator.msSaveBlob(data, `${file}.xls`)
    }

    const el = document.createElement(ele)

    if (typeof el.href !== 'undefined') {
        // 针对普通url
        el.href = typeof data === 'string' ? data : window.URL.createObjectURL(data)
        // 针对blob,edge必须有download属性,且普通url只有edge可以修改文件名
        el.download = `${file}.xls`
        // 兼容fireFox的事件触发
        const evt = document.createEvent('MouseEvents')
        evt.initEvent('click', true, true)
        el.dispatchEvent(evt)
        // 或:
        // document.body.appendChild(el)
        // el.click()
        // document.body.removeChild(el)
    }
}
10、文本框内容复制
/**
 * 文本框内容复制
 * @param {dom} dom dom对象(input)
 */
export const copyInputVal = el => {
    el.select()
    document.execCommand('copy')
}
11、canvas,dataURL,Blob,File相互转换
/**
 * canvas转图片保存,兼容IE10+
 * @param {canvas} canvas canvas对象
 * @param {string} imgName 保存的图片名
 */
export const canvasToImg = (canvas, imgName) => {
    const url = canvas.toDataURL('image/png')
    // 针对IE
    if (window.navigator.msSaveBlob) {
        return window.navigator.msSaveBlob(new Blob([getUint8Arr(url).u8arr]), `${imgName}.png`)
    }
    const a = document.createElement('a')
    a.setAttribute('href', url)
    a.setAttribute('download', `${imgName}.png`)
    const evt = document.createEvent('MouseEvents')
    evt.initEvent('click', true, true)
    a.dispatchEvent(evt)
}

/**
 * canvas转dataURL
 * @param {canvas} canvas
 */
export const convertCanvasToImage = canvas => {
    // let image = new Image()
    // image.src = canvas.toDataURL('image/png')
    return canvas.toDataURL('image/png')
}

/**
 * dataURL转blob对象
 * @param {String} dataurl
 */
export const dataURLtoBlob = dataurl => {
    let uint8 = getUint8Arr(dataurl)
    return new Blob([uint8.u8arr], { type: uint8.mime })
}

/**
 * 将blob转换为file
 * @param {Blob} theBlob
 * @param {String} fileName
 */
export const blobToFile = (theBlob, fileName) => {
    theBlob.lastModifiedDate = new Date()
    theBlob.name = fileName
    return theBlob
}

/**
 * dataURL转file对象
 * @param {String} dataurl
 * @param {String} filename
 */
export const dataURLtoFile = (dataurl, filename) => {//将base64转换为文件
    let uint8 = getUint8Arr(dataurl)
    return new File([uint8.u8arr], filename, { type: uint8.mime })
}

/**
 * 二进制容器
 * @param {String} dataurl
 */
const getUint8Arr = dataurl => {
    // 截取base64的数据内容
    let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        // 获取解码后的二进制数据的长度,用于后面创建二进制数据容器
        n = bstr.length,
        // 创建一个Uint8Array类型的数组以存放二进制数据
        u8arr = new Uint8Array(n)
    // 将二进制数据存入Uint8Array类型的数组中
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return { u8arr, mime }
}
12、生成任意长度的随机序列号
/**
 * 生成任意长度的随机序列号
 * @param {Number} length 长度
 */
export const getRandomCode = length => {
    
    if (length > 0) {
        let data = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z']
        let arr = shuffle(data)
        let nums = ''
        for (let i = 0; i < length; i++) {
            let r = parseInt(Math.random() * 61)
            nums += arr[r]
        }
        return nums
    } else {
        return false
    }
}
13、生成uuid
export const uuid = () => {
    let s = []
    let hexDigits = '0123456789abcdef'
    for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[14] = '4'
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
    s[8] = s[13] = s[18] = s[23] = ''

    let uuid = s.join('')
    return uuid
}
14、随机生成指定长度的值为特定范围内的数字的数组
/**
 * 随机生成指定长度的值为特定范围内的数字的数组
 * @param {Number} min 最小值
 * @param {Number} max 最大值
 * @param {Number} count 个数
 */
export const randomNumArr = (min, max, count) => {
    let arr = []
    for (let i = 0; i < count; i++) {
        arr.push(Math.floor(Math.random() * (max - min + 1) ) + min)
    }
    return arr
}
15、数组求和
/**
 * 数组求和
 * @param {Array} arr 求和的数组
 */
export const sum = arr => {
    let sum = 0
    arr.map(item => sum += item)
    return sum
}

16、手机号加密

/**
 * 手机号加密
 * @param {String} tel 待加密的手机号
 */
export const encryptionTel = tel => {
    return tel ? tel.replace(/^(\d{3})\d{4}(\d+)/, '$1****$2') : tel
}

17、JSON格式化显示

/**
 * JSON格式化显示
 */
export const JSONFormat = json => {
    return JSON.stringify(JSON.parse(json), null, 4)
}

18、AES加密算法

/**
 * 加密算法
 */
import CryptoJS from 'crypto-js'

const key = CryptoJS.enc.Utf8.parse('1234123412ABCDEF') //十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412') //十六位十六进制数作为密钥偏移量

// AES加密
export const AES_Encrypt = str => {
    let srcs = CryptoJS.enc.Utf8.parse(str)
    let encrypted = CryptoJS.AES.encrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    })
    return encrypted.ciphertext.toString().toUpperCase()
}

// AES解密
export const AES_Decrypt = str => {
    let encryptedHexStr = CryptoJS.enc.Hex.parse(str)
    let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
    let decrypt = CryptoJS.AES.decrypt(srcs, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    })
    let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
    return decryptedStr.toString()
}
上一篇下一篇

猜你喜欢

热点阅读