前端常用 utils 工具封装

javascript 复制代码
// 函数防抖
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
}
相关推荐
燃先生._.几秒前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
black^sugar2 小时前
纯前端实现更新检测
开发语言·前端·javascript
2401_857600953 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_857600953 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL3 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
小白学大数据3 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
2402_857583493 小时前
基于 SSM 框架的 Vue 电脑测评系统:照亮电脑品质之路
前端·javascript·vue.js
java_heartLake4 小时前
Vue3之性能优化
javascript·vue.js·性能优化