JS公共方法合集

1、科学计算法

var countDecimals = function(num) {
    var len = 0;
    try {
        num = Number(num);
        var str = num.toString().toUpperCase();
        if (str.split('E').length === 2) { // scientific notation
            var isDecimal = false;
            if (str.split('.').length === 2) {
                str = str.split('.')[1];
                if (parseInt(str.split('E')[0]) !== 0) {
                    isDecimal = true;
                }
            }
            let x = str.split('E');
            if (isDecimal) {
                len = x[0].length;
            }
            len -= parseInt(x[1]);
        } else if (str.split('.').length === 2) { // decimal
            if (parseInt(str.split('.')[1]) !== 0) {
                len = str.split('.')[1].length;
            }
        }
    } catch (e) {
        throw e;
    } finally {
        if (isNaN(len) || len < 0) {
            len = 0;
        }
        return len;
    }
};
 
var convertToInt = function(num) {
    num = Number(num);
    var newNum = num;
    var times = countDecimals(num);
    var temp_num = num.toString().toUpperCase();
    if (temp_num.split('E').length === 2) {
        newNum = Math.round(num * Math.pow(10, times));
    } else {
        newNum = Number(temp_num.replace(".", ""));
    }
    return newNum;
};
 
var getCorrectResult = function(type, num1, num2, result) {
    var temp_result = 0;
    switch (type) {
        case "add":
            temp_result = num1 + num2;
            break;
        case "sub":
            temp_result = num1 - num2;
            break;
        case "div":
            temp_result = num1 / num2;
            break;
        case "mul":
            temp_result = num1 * num2;
            break;
    }
    if (Math.abs(result - temp_result) > 1) {
        return temp_result;
    }
    return result;
};
export default {
    // 加法
    accAdd(num1, num2) {
        num1 = Number(num1);
        num2 = Number(num2);
        var dec1, dec2, times;
        try { dec1 = countDecimals(num1) + 1; } catch (e) { dec1 = 0; }
        try { dec2 = countDecimals(num2) + 1; } catch (e) { dec2 = 0; }
        times = Math.pow(10, Math.max(dec1, dec2));
        // var result = (num1 * times + num2 * times) / times;
        var result = (this.accMul(num1, times) + this.accMul(num2, times)) / times;
        return getCorrectResult("add", num1, num2, result);
        // return result;
    },
    // 减法
    accSub(num1, num2) {
        num1 = Number(num1);
        num2 = Number(num2);
        var dec1, dec2, times;
        try { dec1 = countDecimals(num1) + 1; } catch (e) { dec1 = 0; }
        try { dec2 = countDecimals(num2) + 1; } catch (e) { dec2 = 0; }
        times = Math.pow(10, Math.max(dec1, dec2));
        // var result = Number(((num1 * times - num2 * times) / times);
        var result = Number((this.accMul(num1, times) - this.accMul(num2, times)) / times);
        return getCorrectResult("sub", num1, num2, result);
        // return result;
    },
    // 除法
    accDiv(num1, num2) {
        num1 = Number(num1);
        num2 = Number(num2);
        var t1 = 0,
            t2 = 0,
            dec1, dec2;
        try { t1 = countDecimals(num1); } catch (e) {}
        try { t2 = countDecimals(num2); } catch (e) {}
        dec1 = convertToInt(num1);
        dec2 = convertToInt(num2);
        var result = this.accMul((dec1 / dec2), Math.pow(10, t2 - t1));
        return getCorrectResult("div", num1, num2, result);
        // return result;
    },
    // 乘法
    accMul(num1, num2) {
        num1 = Number(num1);
        num2 = Number(num2);
        var times = 0,
            s1 = num1.toString(),
            s2 = num2.toString();
        try { times += countDecimals(s1); } catch (e) {}
        try { times += countDecimals(s2); } catch (e) {}
        var result = convertToInt(s1) * convertToInt(s2) / Math.pow(10, times);
        return getCorrectResult("mul", num1, num2, result);
        // return result;
    }
}

2、防抖节流插槽版

/**
 * 防抖函数(可用于防止重复提交), 就是指触发事件后在 n 秒内函数只能执行一次
 * 节流函数, 就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率
 *
 * @param func 执行函数
 * @param time 执行时间间隔
 * @param isDebounce 是否防抖或者节流
 * @param ctx event
 */
const debounce = (func, time, isDebounce, ctx) => {
    var timer, lastCall, rtn;
    // 防抖函数
    if (isDebounce) {
        rtn = (...params) => {
            if (timer) clearTimeout(timer);
            timer = setTimeout(() => {
                func.apply(ctx, params);
            }, time);
        };
    // 节流函数
    } else {
        rtn = (...params) => {
            const now = new Date().getTime();
            if (now - lastCall < time && lastCall) return;
            lastCall = now;
            func.apply(ctx, params);
        };
    }
    return rtn;
};

export default {
    name: 'Debounce',
    abstract: true,
    props: {
        time: {
            type: Number,
            default: 800,
        },
        events: {
            type: String,
            default: 'click',
        },
        isDebounce: {
            type: Boolean,
            default: true,
        },
    },
    created() {
        this.eventKeys = this.events.split(',');
        this.originMap = {};
        this.debouncedMap = {};
    },
    render() {
        const vnode = this.$slots.default[0];
        this.eventKeys.forEach(key => {
            const target = vnode.data.on[key];
            if (target === this.originMap[key] && this.debouncedMap[key]) {
                vnode.data.on[key] = this.debouncedMap[key];
            } else if (target) {
                this.originMap[key] = target;
                this.debouncedMap[key] = debounce(
                    target,
                    this.time,
                    this.isDebounce,
                    vnode
                );
                vnode.data.on[key] = this.debouncedMap[key];
            }
        });
        return vnode;
    },
};

使用方法:

 <Debounce :time='200' >
            <el-button @click.native="handleUserLogin">登录</el-button>
        </Debounce>



main.js

// 防抖 or 节流
import Debounce from '@/utils/debounce'
Vue.component('Debounce', Debounce)

3、其他公共方法(待完善)

/**
 * 防抖函数(可用于防止重复提交)
 * 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,
 * 如果设定时间到来之前,又触发了事件,就重新开始延时。也就是说当一个用户一直触发这个函数,
 * 且每次触发函数的间隔小于既定时间,那么防抖的情况下只会执行一次。
 *
 * @param fn 执行函数
 * @param delay 间隔时间
 */
function debounce (fn, delay) {
    let timeout = null;
    return function() {
        if (timeout) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(() => {
            this[fn](); // 兼容vue函数 
        }, delay);
    };
}


/**
 * 节流函数
 * 当持续触发事件时,保证在一定时间内只调用一次事件处理函数
 * 小于既定值,函数节流会每隔这个时间调用一次
 *
 * @param fn 执行函数
 * @param delay 间隔时间
 */
 function throttle(fn, delay){
    let lastCall = 0;
    let throttled = function() {
        const now = new Date().getTime();
        // remaining 不触发下一次函数的剩余时间
        if (now - lastCall < delay && lastCall) return;
            lastCall = now;
            this[fn].apply(this, arguments);
    }
    return throttled;
}


/**
 * 时间戳转换方法
 *
 * @param timestamp  时间戳
 * @param format 时间格式
 */
function formatDate (timestamp, format = 'YYYY-MM-dd HH:mm:ss') {
    let time = new Date(timestamp)
    // 获取年月日时分秒,使用es6 padStart补0
    let year = time.getFullYear()
    const month = (time.getMonth() + 1).toString().padStart(2, '0')
    const date = (time.getDate()).toString().padStart(2, '0')
    const hours = (time.getHours()).toString().padStart(2, '0')
    const minute = (time.getMinutes()).toString().padStart(2, '0')
    const second = (time.getSeconds()).toString().padStart(2, '0')

    // 替换时间格式
    format = format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('dd', date)
    .replace('HH', hours)
    .replace('mm', minute)
    .replace('ss', second)

    return format
}


// 数组去重
function dedupe (array){
    return Array.from(new Set(array));
}

// 对象深克隆
function deepClone (o) {
    // 判断如果不是引用类型,直接返回数据即可
    if (typeof o === 'string' || typeof o === 'number' || typeof o === 'boolean' || typeof o === 'undefined') {
        return o
    } else if (Array.isArray(o)) { // 如果是数组,则定义一个新数组,完成复制后返回
        // 注意,这里判断数组不能用typeof,因为typeof Array 返回的是object
        var _arr = []
        o.forEach(item => { _arr.push(item) })
        return _arr
    } else if (typeof o === 'object') {
        var _o = {}
        for (let key in o) {
            _o[key] = deepClone(o[key])
        }
        return _o
    }
}

/**
 * 下划线转驼峰
 * @param string
 * @returns {*}
 */
export function underLine2CamelCase(string){
  return string.replace( /_([a-z])/g, function( all, letter ) {
    return letter.toUpperCase();
  });
}

export {
    debounce,
    throttle,
    formatDate,
    dedupe,
    deepClone,
    underLine2CamelCase,
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值