工具函数
@erp/common 提供的工具函数集合,涵盖类型判断、防抖节流、对象操作、日期处理等常用功能。
功能分类
- 类型判断 -
isString/isNumber/isArray/isObject/isFunction等 - 防抖节流 -
debounce/throttleByRaf - 对象操作 -
omit/pick/getValueByPath - 日期处理 -
dayjs/getNow/getDayjsValue - DOM 操作 -
on/off/contains/scrollIntoView - 剪贴板 -
clipboard
引入方式
typescript
import {
isString, isNumber, isArray, isObject,
debounce, throttleByRaf,
omit, pick,
clipboard,
dayjs
} from '@erp/common'类型判断
isString
判断值是否为字符串。
typescript
isString(value: any): value is string
// 示例
isString('hello') // true
isString(123) // false
isString('') // trueisNumber
判断值是否为数字(排除 NaN)。
typescript
isNumber(value: any): value is number
// 示例
isNumber(123) // true
isNumber(0) // true
isNumber(NaN) // false
isNumber('123') // falseisBoolean
判断值是否为布尔值。
typescript
isBoolean(value: unknown): value is boolean
// 示例
isBoolean(true) // true
isBoolean(false) // true
isBoolean(1) // false
isBoolean('true') // falseisArray
判断值是否为数组。
typescript
isArray(value: any): value is any[]
// 示例
isArray([]) // true
isArray([1, 2]) // true
isArray({}) // false
isArray('array') // falseisObject
判断值是否为普通对象。
typescript
isObject<T>(value: T): value is Extract<T, Record<string, any>>
// 示例
isObject({}) // true
isObject({ a: 1 }) // true
isObject([]) // false
isObject(null) // false
isObject(new Date()) // falseisFunction
判断值是否为函数。
typescript
isFunction(value: any): value is (...args: any[]) => any
// 示例
isFunction(() => {}) // true
isFunction(function() {}) // true
isFunction(class {}) // true
isFunction({}) // falseisNull
判断值是否为 null。
typescript
isNull(value: any): value is null
// 示例
isNull(null) // true
isNull(undefined) // false
isNull(0) // falseisUndefined
判断值是否为 undefined。
typescript
isUndefined(value: any): value is undefined
// 示例
isUndefined(undefined) // true
isUndefined(null) // false
isUndefined(void 0) // trueisPromise
判断值是否为 Promise。
typescript
isPromise<T>(value: unknown): value is Promise<T>
// 示例
isPromise(Promise.resolve()) // true
isPromise(new Promise(() => {})) // true
isPromise({ then: () => {} }) // falseisDate
判断值是否为 Date 对象。
typescript
isDate(value: any): boolean
// 示例
isDate(new Date()) // true
isDate('2024-01-01') // false
isDate(Date.now()) // falseisRegExp
判断值是否为正则表达式。
typescript
isRegExp(value: any): boolean
// 示例
isRegExp(/test/) // true
isRegExp(new RegExp('a')) // true
isRegExp('/test/') // falseisColor
判断值是否为有效的颜色值(支持 HEX、RGB、RGBA)。
typescript
isColor(value: any): boolean
// 示例
isColor('#fff') // true
isColor('#ffffff') // true
isColor('rgb(255,255,255)') // true
isColor('rgba(0,0,0,0.5)') // true
isColor('red') // falseisEmptyValue
判断值是否为空值。
typescript
isEmptyValue(value: any): boolean
// 空值定义:
// - 字符串:空字符串或只有空格
// - 数组:空数组或元素全为 null/undefined
// - 对象:空对象
// - 数字:NaN
// - null 或 undefined
// 示例
isEmptyValue('') // true
isEmptyValue(' ') // true
isEmptyValue([]) // true
isEmptyValue([null]) // true
isEmptyValue({}) // true
isEmptyValue(NaN) // true
isEmptyValue(null) // true
isEmptyValue(undefined) // true
isEmptyValue(0) // false
isEmptyValue('0') // false
isEmptyValue([0]) // falseisEmptyObject
判断值是否为空对象。
typescript
isEmptyObject(value: any): boolean
// 示例
isEmptyObject({}) // true
isEmptyObject({ a: 1 }) // false
isEmptyObject([]) // falseisExist
判断值是否存在(非空且非 undefined,但 0 视为存在)。
typescript
isExist(value: any): boolean
// 示例
isExist(0) // true
isExist('') // false
isExist(null) // false
isExist(undefined) // false
isExist('hello') // trueisWindow
判断值是否为 window 对象。
typescript
isWindow(value: any): value is Window
// 示例
isWindow(window) // true
isWindow(document) // falseisDayjs
判断值是否为 dayjs 对象。
typescript
isDayjs(value: any): value is Dayjs
// 示例
import { dayjs } from '@erp/common'
isDayjs(dayjs()) // true
isDayjs(new Date()) // false
isDayjs('2024-01-01') // false防抖节流
debounce
防抖函数,在指定延迟时间内只执行最后一次调用。
typescript
debounce(callback: (...args: any[]) => void, delay: number): (...args: any[]) => void
// 示例
const handleSearch = debounce((keyword: string) => {
console.log('搜索:', keyword)
}, 300)
// 快速连续调用,只会执行最后一次
handleSearch('a')
handleSearch('ab')
handleSearch('abc') // 300ms 后执行使用场景:
- 搜索框输入
- 窗口 resize 事件
- 按钮防重复点击
throttleByRaf
基于 requestAnimationFrame 的节流函数,适用于动画和滚动场景。
typescript
throttleByRaf(
callback: (...args: any[]) => void,
options?: { trailing?: boolean; leading?: boolean }
): { (...args: any[]): void; cancel: () => void }
// 示例
const handleScroll = throttleByRaf(() => {
console.log('滚动位置:', window.scrollY)
})
window.addEventListener('scroll', handleScroll)
// 取消节流
handleScroll.cancel()使用场景:
- 滚动事件处理
- 拖拽位置更新
- 动画帧更新
对象操作
omit
从对象中排除指定的属性,返回新对象。
typescript
omit<T, K>(object: T, keys: K[]): Omit<T, K>
// 示例
const user = { id: 1, name: '张三', password: '123456', age: 25 }
omit(user, ['password'])
// { id: 1, name: '张三', age: 25 }
omit(user, ['password', 'age'])
// { id: 1, name: '张三' }pick
从对象中选取指定的属性,返回新对象。
typescript
pick<T, K>(object: T, keys: K[]): Pick<T, K>
// 示例
const user = { id: 1, name: '张三', password: '123456', age: 25 }
pick(user, ['id', 'name'])
// { id: 1, name: '张三' }
pick(user, ['name', 'age'])
// { name: '张三', age: 25 }getValueByPath
根据路径获取对象中的值。
typescript
import { getValueByPath } from '@erp/common'
const obj = {
user: {
profile: {
name: '张三',
address: {
city: '北京'
}
}
}
}
getValueByPath(obj, 'user.profile.name')
// '张三'
getValueByPath(obj, 'user.profile.address.city')
// '北京'
getValueByPath(obj, 'user.profile.phone')
// undefined数组操作
toArray
将值转换为数组。
typescript
import { toArray } from '@erp/common'
toArray('hello') // ['hello']
toArray(['a', 'b']) // ['a', 'b']
toArray(undefined) // []
toArray(null) // []剪贴板
clipboard
复制文本到剪贴板。
typescript
clipboard(text: string): Promise<void>
// 示例
import { clipboard } from '@erp/common'
// 复制文本
await clipboard('Hello World')
// 在按钮点击中使用
const handleCopy = async () => {
try {
await clipboard('要复制的内容')
console.log('复制成功')
} catch (error) {
console.error('复制失败', error)
}
}日期处理
dayjs
内置的 dayjs 实例,已扩展常用插件。
typescript
import { dayjs } from '@erp/common'
// 基础用法
dayjs() // 当前时间
dayjs('2024-01-01') // 解析日期
dayjs().format('YYYY-MM-DD') // 格式化
dayjs().add(1, 'day') // 加一天
dayjs().subtract(1, 'month') // 减一月
// 已加载的插件
// - customParseFormat: 自定义解析格式
// - isBetween: 判断是否在范围内
// - weekOfYear: 获取周数
// - advancedFormat: 高级格式化
// - weekYear: 周年
// - quarterOfYear: 季度getNow
获取当前时间的 dayjs 对象。
typescript
import { getNow } from '@erp/common'
const now = getNow()
console.log(now.format('YYYY-MM-DD HH:mm:ss'))getDayjsValue
将日期值转换为 dayjs 对象。
typescript
import { getDayjsValue } from '@erp/common'
// 单个值
getDayjsValue('2024-01-01', 'YYYY-MM-DD')
// Dayjs 对象
// 数组
getDayjsValue(['2024-01-01', '2024-12-31'], 'YYYY-MM-DD')
// [Dayjs, Dayjs]getDateValue
将 dayjs 对象转换为 Date 对象。
typescript
import { getDateValue, dayjs } from '@erp/common'
getDateValue(dayjs())
// Date 对象
getDateValue([dayjs(), dayjs().add(1, 'day')])
// [Date, Date]DOM 操作
on / off
添加/移除事件监听器。
typescript
import { on, off } from '@erp/common'
const handleClick = (e: MouseEvent) => {
console.log('clicked', e)
}
// 添加事件
on(document.body, 'click', handleClick)
// 移除事件
off(document.body, 'click', handleClick)contains
判断一个节点是否包含另一个节点。
typescript
import { contains } from '@erp/common'
contains(parentElement, childElement)
// true 或 falsegetElement
根据选择器或元素获取 DOM 元素。
typescript
import { getElement } from '@erp/common'
getElement('#app') // 通过 ID
getElement('.container') // 通过类名
getElement(domElement) // 直接返回元素getRelativeRect
获取两个元素之间的相对位置。
typescript
import { getRelativeRect } from '@erp/common'
const rect = getRelativeRect(targetElement, relativeElement)
// { top, bottom, left, right, width, height }isScroll
判断元素是否可滚动。
typescript
import { isScroll } from '@erp/common'
isScroll(element) // true 或 falsegetScrollBarWidth
获取滚动条宽度。
typescript
import { getScrollBarWidth } from '@erp/common'
const width = getScrollBarWidth(element)getParentScroller
获取元素的滚动父容器。
typescript
import { getParentScroller } from '@erp/common'
const scroller = getParentScroller(element)checkElInView
检查元素是否在可视区域内。
typescript
import { checkElInView } from '@erp/common'
// 检查元素是否在窗口可视区域
checkElInView(element)
// 检查元素是否在指定容器可视区域
checkElInView(element, containerElement)
// 带预加载因子
checkElInView(element, window, 1.5)滚动
scrollIntoView
将元素滚动到可视区域。
typescript
import { scrollIntoView } from '@erp/common'
scrollIntoView(element, {
behavior: 'smooth', // 平滑滚动
block: 'center', // 垂直居中
inline: 'nearest' // 水平最近
})computeScrollIntoView
计算滚动到可视区域所需的滚动量。
typescript
import { computeScrollIntoView } from '@erp/common'
const actions = computeScrollIntoView(element, {
block: 'center',
inline: 'nearest'
})
// 返回需要执行的滚动操作数组弹出层
getPopupStyle
获取弹出层的定位样式。
typescript
import { getPopupStyle } from '@erp/common'
const style = getPopupStyle(triggerRect, popupRect, position)getElementScrollRect
获取元素相对于滚动容器的位置。
typescript
import { getElementScrollRect } from '@erp/common'
const rect = getElementScrollRect(element, containerRect)