前端常用 utils 工具封装


// 函数防抖
export function debounce(fn, interval) {
    let timer
    return function (this, ...args) {
        clearTimeout(timer)
        const context = this
        let params = [...args]
        timer = setTimeout(() => {
            fn.call(context, ...params)
        }, interval || 1000)
    }
}

// 函数节流
export function throttle(fn, interval) {
    let timer = null
    return function (this, ...args) {
        const context = this
        let params = [...args]
        if (!timer) {
            timer = setTimeout(() => {
                fn.call(context, ...params)
                timer = null
            }, interval || 1000)
        }
    }
}

// 对象数组去重(Map 新的写法,可能不兼容 低版本的浏览器)
export function uniqueArr(arr = [], key) {
    return Array.from(new Map(arr.map((item) => [item[key], item])))
}

// 对象数组去重(老语法)
export function oldUniqueArr(arr = [], key) {
    if (!key) return new Error("请传入 key")
    const tempObj = {}
    const newArray = []
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        if (!tempObj.hasOwnProperty(item[key])) {
            tempObj[item[key]] = item
            newArray.push(item)
        }
    }
    return newArray
}

// 多维数组转成一维数组
export function flattenArray(arr) {
    return arr.reduce((acc, item) => {
        return acc.concat(Array.isArray(item) ? flattenArray(item) : item)
    }, [])
}

// 二维数组根据指定的key 转成一维数组
export function flattenAndUniqueByKey(arr, key) {
    // Array.prototype.flat() 方法将二维数组扁平化为一维数组。
    const flatArray = arr.flat();
    // 使用 Map 去重
    const uniqueMap = new Map();
    flatArray.forEach(item => {
        uniqueMap.set(item[key], item);
    });
    return Array.from(uniqueMap.values());
}

// 二维数组根据指定的key 转成一维数组(旧版语法)
export function oldFlattenAndUniqueByKey(arr, key) {
    let uniqueObj = {}
    let uniqueArray = []
    arr.reduce((acc, childArr) => {
        childArr.forEach(item => {
            // 根据传入的 key,做 key
            uniqueObj[item[key]] = item;
        })
        return acc
    }, [])

    for (const key in uniqueObj) {
        uniqueArray.push(uniqueObj[key])
    }
    return uniqueArray
}

// const url = 'https://example.com/page?name=Alice&age=30&city=Wonderland';
// 获取 url 参数
export function getQueryParams(url) {
    const queryParams = {};
    // 找到 URL 中的查询字符串部分
    const queryString = url.split('?')[1];
    // 将查询字符串按 & 分割为参数对
    const pairs = queryString.split('&');
    // 遍历每个参数对
    pairs.forEach(pair => {
        const [key, value] = pair.split('=');
        // 对值进行解码并存储到对象中
        queryParams[decodeURIComponent(key)] = decodeURIComponent(value || '');
    });
    return queryParams;
}


// 判断两个对象是否相等
export function objectIsEqual(a, b) {
    if (!a || !b) return false
    const aProps = Object.getOwnPropertyNames(a)
    const bProps = Object.getOwnPropertyNames(b)
    if (aProps.length !== bProps.length) return false
    for (let i = 0; i < aProps.length; i++) {
        const propName = aProps[i]
        const propA = a[propName]
        const propB = b[propName]
        if (!b.hasOwnProperty(propName)) return false
        if (propA instanceof Object) {
            if (!isObjectValueEqual(propA, propB)) return false
        } else if (propA !== propB) {
            return false
        }
    }
    return true
}


// 延迟执行
export function delay(time) {
    return new Promise(resolve => setTimeout(resolve, time))
}

// 正则验证手机号
export function isPhone(str = "") {
    const phoneRex =
        /^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/
    return phoneRex.test(str)
}


// 获取数据类型
export function typeOfData(data) {
    return Object.prototype.toString.call(data).slice(8, -1)
}

export function buildTree(items, parentKey = 'parentId', idKey = 'id', rootParentId = null) {
    // 创建一个 map 来存储每个 id 和其对应的节点
    const itemMap = new Map();
    // 遍历数组,初始化每个节点
    items.forEach(item => {
        itemMap.set(item[idKey], { ...item, children: [] });
    });
    // 组装树形结构
    const tree = [];
    itemMap.forEach(node => {
        const parentId = node[parentKey];
        if (parentId === rootParentId) {
            // 如果节点的 parentKey 与 rootParentId 匹配,则为树的根节点
            tree.push(node);
        } else {
            // 否则,找到其父节点,并将其添加到父节点的 children 数组中
            const parentNode = itemMap.get(parentId);
            if (parentNode) {
                parentNode.children.push(node);
            }
        }
    });
    return tree;
}


// 时间格式化
// date 对象 dateFormat("YYYY-mm-dd HH:MM:ss", new Date(毫秒级时间戳)),
export function dateFormat(fmtStr, date) {
    let fmt = fmtStr
    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(), // 秒
        "s+": date.getMilliseconds().toString(),
        // 有其他格式化字符需求可以继续添加,必须转化成字符串
    }
    for (const k in opt) {
        if (Object.prototype.hasOwnProperty.call(opt, k)) {
            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
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清云随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值