前端常用 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
}
相关推荐
_Legend_King几秒前
vue3 + elementPlus 日期时间选择器禁用未来及过去时间
javascript·vue.js·elementui
余生H2 分钟前
transformer.js(三):底层架构及性能优化指南
javascript·深度学习·架构·transformer
景天科技苑15 分钟前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
前端·javascript·vue.js·vite·vue项目·脚手架工具
石小石Orz24 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
小行星12526 分钟前
前端预览pdf文件流
前端·javascript·vue.js
join828 分钟前
解决vue-pdf的签章不显示问题
javascript·vue.js·pdf
小行星12533 分钟前
前端把dom页面转为pdf文件下载和弹窗预览
前端·javascript·vue.js·pdf
土豆湿1 小时前
拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
开发语言·javascript·css
J总裁的小芒果1 小时前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
Lei_zhen961 小时前
记录一次electron-builder报错ENOENT: no such file or directory, rename xxxx的问题
前端·javascript·electron