前言
项目当中有各种公用的utils 方法需要整合,这里给大家分享几个比较好用的方法
1. 获取深层数据
/**
* 提取深层数据的值 (防止中间项 不存在导致的报错)
* @param obj any 数据源
* @param keyArr string|number[] key数组
* @returns any
*/
export function getDeepValue(obj, keyArr) {
return keyArr.reduce((acc, key) => acc && acc[key], obj)
}
// eg:
var res = {
a: {
list: [{name: 'item1', id: '1'}]
},
b: [
{name: 'b', id: 'b1', children: [{ name: 'b2', id: 'b2' }]}
]
}
getDeepValue(res, ['b', 0, 'children', 0, 'name']) // 'b2'
getDeepValue(res, ['a', 'list', 0, 'name']) // 'item1'
2. 自定义log打印
/**
* @param content 数据源
* @param title string
* @param background string
*/
export function custLog(content, title = 'title', background = '#007bfc') {
content = typeof content === 'object' ? JSON.stringify(content) : content
console.log.apply(null, [
`%c ${title}: %c ${content} `,
'padding: 1px; border-radius: 10px; color: #fff; background: #9159B2;',
`padding: 1px; border-radius: 10px; color: #fff; background: ${background};`
])
}
custLog({a: [{b: 'b'}], c: 123})
custLog('自定义', 'custTitle', 'orange')
打印引用数据
打印字符串 title声明
3. 函数防抖/节流
- 防抖:指定时间内 频繁触发一个事件,只触发最后一次
- 节流:指定时间内 频繁触发一个事件,只会触发一次
/**
* @desc 函数防抖
* @param func 函数
* @param wait number 延迟毫秒数
* @param immediate boolean 立即执行
*/
export function debounce(func, wait = 1000, immediate = false) {
let timeout
const _clear = () => {
clearTimeout(timeout)
timeout = null
}
return function () {
const bool = !timeout
if (immediate && bool) func.apply(this, arguments)
if (timeout) _clear()
timeout = setTimeout(function () {
func.apply(this, arguments)
}, wait)
if (bool) _clear()
}
}
/**
* @desc 函数防抖
* @param func 函数
* @param wait number 延迟毫秒数
* @param immediate boolean 立即执行
*/
export function throttle(func, wait = 1000, immediate = false) {
let t_start = 0
return function () {
const args = arguments
if (!t_start) {
t_start = +new Date()
if (immediate) func.apply(this, args)
}
const t_end = +new Date()
if (t_end - t_start >= wait) {
func.apply(this, args)
t_start = t_end
}
}
}
4. 文字复制
/**
* 复制文字
* @param val
* @returns {boolean}
*/
export function copyText(val) {
const textarea = document.createElement('textarea')
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
textarea.value = val
document.body.appendChild(textarea)
textarea.select()
const res = document.execCommand('copy')
document.body.removeChild(textarea)
return res
}
5. 异步操作未完成前加锁
/**
* 异步操作避免重复触发加锁
* @param syncFn
* @returns {(function(...[*]): Promise<void>)|*}
*/
export function asyncHandlerLockWrap(syncFn) {
let is_lock = false
return async function (...args) {
const context = this
if (!is_lock) {
is_lock = true
Promise.resolve()
.then(syncFn.bind(context, ...args))
.finally(() => {
is_lock = false
})
}
}
}
//eg: 点击按钮触发接口调用, 存在误操作或者恶意操作的情况时 等异步回调结束才允许再次触发
var btnClick = asyncHandlerLockWrap(() => {
// 模拟调用接口
return new Promise((s) => {
setTimeout(s, 5000)
}).then(() => {
console.log('完成')
return 'success'
})
})
// <button onClick={btnClick}>提交</button>
6. formatNumber 转金额数字
/**
* 转化成带逗号的number格式
* @param num string|number
* @param minimumFractionDigits 保留小数位
* @returns {string}
*/
export function formatNumber(num, minimumFractionDigits = 0) {
return (+num || 0).toLocaleString('zh', { minimumFractionDigits })
}
formatNumber(15, 2) // '15.00'
formatNumber(123456.3, 2) // '123,456.30'
formatNumber('123.45', 2) // '123.45'
推荐
分享给大家一个Vue3 + Ts + Element-plus & Vite 搭建,开箱即用的后台管理项目,
手机端已兼容,如果觉得不错希望可以得到各位大佬的star
文件地址: src/layout/components/CheckUpdates
项目链接 github.com/LanceJiang/…
访问链接
lancejiang.github.io/Lance-Eleme…