目录
# 包含所有的 utils
pnpm add @utopia-utils/core
# 如果只需要使用树结构 utils
pnpm add @utopia-utils/tree
- breadthFirstTraverse: 广度优先遍历。source
- deepFirstTraverse: 深度优先遍历。source
- treeFindNode: 查找符合条件的单个节点或多个节点,通过广度优先遍历查找。source
- buildTreeFromList: 列表结构转树结构。source
- flattenTree: 打平,树结构转列表结构。source
- treeFindPath: 查打符合条件节点的路径。source
- treeFilterNode: 过滤不符合条件的树节点。source
# 如果只需要使用 Dom utils
pnpm add @utopia-utils/dom
- waitForSelector: 等待指定的选择器匹配的元素出现在页面中,如果调用此方法时已经有匹配的元素,那么此方法立即返回。 如果指定的选择器在超时时间后扔不出现,返回
null
。source - panzoom: 为指定的元素添加拖拽缩放功能。source
- canUseDom: 判断是否可以使用
document
和window
对象,判断是否是 ssr 场景。source - domContains: 原生
Node.contains()
的兼容写法 。source - updateCSS: 注入 css 样式(通过动态插入 style 标签)。source
- isAlipay: 判断是否是支付宝浏览器。source
- isAndroid: 判断是否是 Android 系统。source
- isIOS: 判断是否是 IOS 系统。source
- isWeixin: 判断是否是微信浏览器。source
- isMobile: 判断是否是移动端浏览器。source
- loadCSS: 动态加载 CSS。source
- loadScript: 动态加载脚本。source
- setCssVar: 设置
css
变量。 source - checkWebpFeature: 检测浏览器是否支持 webp 的一些特性('lossy' | 'lossless' | 'alpha' | 'animation')。source
- checkWebpSupport: 检测浏览器是否支持 webp。source
- defineDictionary: 定义业务字典。 typesafe source
createEnumFromOptions: 通过options
自动生成对应的enum
, 后期只需要维护options
。typesafe。source- sleep: 等待指定的时间。source
- retry: 重试函数(如果函数抛出错误)直到成功或者达到最大重试次数。source
- objectKeys: 带类型的
Object.keys()
。source - omit: 删除
object
对象的指定属性。source - pick: 从
object
对象中获取指定属性。source - randomInt: 生成指定范围内
[min, max]
的整数。source - awaitTo: Async await wrapper for easy error handling without try-catch。source
- escapeStringRegexp: 把字符串中的特殊字符转义为它可以在正则表达式中使用的形式。source
- toFixedWithoutZeros:
Number.toFixed
并移除末尾的零。source - average: 计算数组的平均值,支持
object
。source - sum: 计算数组的和,支持
object
。source - sort: 数组排序,支持
object
。source - alphabetical: 数组按字母顺序排序,支持
object
。source - debounce: 防抖。(export from throttle-debounce)
- throttle: 节流。(export from throttle-debounce)
- callLimit: 限制函数调用次数。source
- once: 限制函数只能调用一次。source
- encryptPhone: 加密手机号, 中间 4 位显示成 *。source
- getByPath: 通过路径获取对象的值。typesafe source
- setByPath: 通过路径设置对象的值。typesafe source
- arrayToCSV: 数组转换为 CSV 字符串。source
- memoize: 创建一个会缓存返回结果的函数。source
- getFileName: 获取文件名。source
- Cookies: cookie utils.(export from js-cookie)
- NP: 🚀1K tiny & 解决浮点数计算错误.(export from number-precision)
- mitt: event emitter / pubsub, typesafe.(export from mitt)
- merge: Merge two objects x and y deeply, returning a new merged object with the elements from both x and y.(export from deepmerge)
- merge.all: Merges any number of objects into a single result object.(export from deepmerge)
- unique: 数组去重。source
- union: 数组并集。source
- uniqueWith: 数组去重,使用自定义的比较函数。source
- intersection: 两个数组交集。source
- deepClone: 深拷贝。source
- deepEqual: 深比较。source
- compose: 函数组合, 从右到左执行。source
- pipe: 函数组合, 从左到右执行。source
- onlyResolvesLast: 解决竞态问题,只保留最后一次调用的结果。source
- parseQuery: 解析 url query。source
- groupBy: 数组根据指定的 key 分组。source
- arrLast: 获取数组最后一个元素。source
- onTimeout: wrap for setTimeout, return a function to remove the timeout。source
- onWindowFocus: 监听 window focus 和 visibilitychange 事件,当窗口可见时,触发回调。source
- formatNumberThousand: 数字千分位格式化。source
- base64ToFile: base64 转 File, 如图片裁剪时,我们获取到的是 base64,但上传接口一般需要 formData 上传。source
- toBase64: 将 File | Blob | imgUrl 转 base64。source
- yuanToFen: 人民币:元转分。source
- fenToYuan: 人民币:分转元。source
- yuanFormat: 人民币格式化(单位默认是分,会进行分转元再格式化)。source
- formatterBankCard: 银行卡号格式化。source
- formatterPhoneNumber: 手机号格式化。source
- formatterIdCard: 身份证呈格式化。source
- desensitizeName: 姓名脱敏。source
- desensitizePhone: 手机号脱敏。source
- desensitizeIdCard: 身份证脱敏。source
- desensitizeEmail: 邮箱脱敏。source
- createPoll: 创建一个轮询器。source
- createControledPromise: 创建一个可控的 Promise。source
# 如果只需要使用类型判断 utils
pnpm add @utopia-utils/share
- isBoolean
- isString
- isNumber
- isFunction
- isSymbol
- isArray
- isRegExp
- isMap
- isPromise
- isSet
- isDate
- isPlainObject
- isObject
- isIntegerKey
- isUndef
- isDef
- isEmpty source
- isNumberLike source
- isValidUrl source
@utopia-utils/core 导出了下面这些 package
- debounce: 防抖。
- throttle: 节流。
- js-cookie: A simple, lightweight JavaScript API for handling browser cookies.
- mitt: 🥊 Tiny 200 byte functional event emitter / pubsub. typesafe.
file-saver
: An HTML5 saveAs() FileSaver implementation.zod
: TypeScript-first schema validation with static type inference.dayjs
: ⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API.any-rule
: 常用正则大全。fast-deep-equal
: The fastest deep equality check with Date, RegExp and ES6 Map, Set and typed arrays support.big.js
: 一个小型,快速的 JavaScript 库,用于任意精度的十进制算术运算。browser-image-compression
: Javascript module to be run in the web browser for image compression.hashids
: generate YouTube-like ids from numbers.
定义业务字典, typesafe
// at src/constant.ts
const { get_MUSIC_TYPE_KEYS, get_MUSIC_TYPE_KV, get_MUSIC_TYPE_MAP, get_MUSIC_TYPE_MAP_BY_KEY, get_MUSIC_TYPE_MAP_BY_VALUE, get_MUSIC_TYPE_OPTIONS, get_MUSIC_TYPE_VALUES, get_MUSIC_TYPE_VK } = defineDictionary([
{
key: 'POP',
value: 1,
label: '流行音乐',
color: 'red',
},
{
key: 'ROCK',
value: 2,
label: '摇滚音乐',
color: 'blue',
},
] as const, 'MUSIC_TYPE') // !!! as const is required for type safe
export const MUSIC_TYPE_KEYS = get_MUSIC_TYPE_KEYS()
// ['POP', 'ROCK']
export const MUSIC_TYPE_VALUES = get_MUSIC_TYPE_VALUES()
// [1, 2]
export const MUSIC_TYPE_KV = get_MUSIC_TYPE_KV()
// { POP: 1, ROCK: 2 }
export const MUSIC_TYPE_VK = get_MUSIC_TYPE_VK()
// { 1: 'POP', 2: 'ROCK' }
export const MUSIC_TYPE_MAP_BY_KEY = get_MUSIC_TYPE_MAP_BY_KEY()
// POP: {
// key: 'POP',
// value: 1,
// label: '流行音乐',
// color: 'red',
// },
// ROCK: {
// key: 'ROCK',
// value: 2,
// label: '摇滚音乐',
// color: 'blue',
// },
export const MUSIC_TYPE_MAP_BY_VALUE = get_MUSIC_TYPE_MAP_BY_VALUE()
// 1: {
// key: 'POP',
// value: 1,
// label: '流行音乐',
// color: 'red',
// },
// 2: {
// key: 'ROCK',
// value: 2,
// label: '摇滚音乐',
// color: 'blue',
// },
export const MUSIC_TYPE_MAP = get_MUSIC_TYPE_MAP()
// { POP: 1, ROCK: 2 }
export const MUSIC_TYPE_OPTIONS = get_MUSIC_TYPE_OPTIONS()
// [
// {
// key: 'POP',
// value: 1,
// label: '流行音乐',
// color: 'red',
// },
// {
// key: 'ROCK',
// value: 2,
// label: '摇滚音乐',
// color: 'blue',
// }
// ]
通过 options
自动生成对应的 enum
, 后期只需要维护 options
。typesafe
废弃, 使用 defineDictionary 代替。
// example
const optionsLevel = [
{
value: 0,
label: 'level1',
},
{
value: 1,
label: 'level2',
},
] as const // as const is required to make the typesafe
const enumLevel = createEnumFromOptions(optionsLevel)
console.log(enumLevel.level1) // 0
console.log(enumLevel['0']) // 'level1'
console.log(enumLevel)
// {
// "0": "level1",
// "1": "level2",
// "level1": 0,
// "level2": 1
// }
重试函数(如果函数抛出错误)直到成功或者达到最大重试次数。
let callNum = 0
function fn() {
callNum++
return Promise.reject(new Error('foo'))
}
const [err, res] = await retry(fn, 2, (attemptTime) => {
return attemptTime * 5
})
// output
// err is Error, res is null, callNum is 3
// execute time is greater than or equal to 15
所有的 Tree utils 支持定义 fieldName
export interface FieldNames { id?: string children?: string parentId?: string }
广度优先遍历。
// example
const tree = [
{
name: 'a',
Children_: [
{ name: 'b' },
],
},
{
name: 'c',
},
]
breadthFirstTraverse(tree, node => console.log(node.name), {
fieldNames: {
children: 'Children_', // default is children
},
})
// output 'a', 'c', 'b'
查找符合条件的单个节点或多个节点,通过广度优先遍历查找。
// example
const tree = [
{
name: 'a',
children: [
{ name: 'b' },
],
}
]
const res = treeFindNode(tree, node => node.name === 'b') // res is [{ name: 'b' }]
列表结构转树结构。
// example
const list = [
{ uid: '1', title: 'node 1', pid: '' },
{ uid: '1-1', title: 'node 1-1', pid: '1' },
{ uid: '1-2', title: 'node 1-2', pid: '1' },
{ uid: '1-1-1', title: 'node 1-1-1', pid: '1-1' },
]
interface TreeNode {
key: string
title: string
children: TreeNode[]
pid: string
}
const tree = buildTreeFromList<TreeNode>(list, {
listFieldNames: { id: 'uid', parentId: 'pid', children: '_Children' },
treeFieldNames: { id: 'key', parentId: 'pid', children: 'children' },
})
打平,树结构转列表结构。
// example
const tree = {
id: 1,
children: [
{
id: 2,
},
],
}
const list = flattenTree(tree)
console.log(list)
// output
// [
// {
// "ID": 1,
// "children": [
// {
// "ID": 2,
// },
// ],
// },
// {
// "ID": 2,
// },
// ]
查打符合条件节点的路径。
// example
const tree = [
{
name: 'a',
children: [
{ name: 'b' },
],
},
{
name: 'c',
},
]
const path = treeFindPath(tree, node => node.name === 'b')
console.log(path?.map(v => v.name)) // ['a', 'b']
过滤不符合条件的树节点。
const tree = [
{
id: 'root',
children: [
{
id: 'child1',
},
{
id: 'child2',
},
],
},
]
treeFilterNode(tree, node => node.id.includes('1'))
// output
// [
// {
// children: [
// {
// id: 'child1',
// },
// ],
// id: 'root',
// },
// ]