Skip to content

Repository files navigation

ui-utils-kit

ui-utils-kit 是一个偏业务的前端工具函数库。

GitHub StarsNPM VersionNPM DownloadsBundle SizeJSDocsLicense


📝 changelogs

TodoList

  • bussiness.captureElementAsImage 支持 html-to-image 的 选择?

  • 2024-12-06
    • 新增 tree 模块,提供树形数据操作的工具函数。
    • 新增 business 模块,提供 DOM 转图片的工具函数。
    • 新增 common 模块,提供一些常用的业务工具函数。
    • 完善文档说明。
  • 2025-04-24
    • 新增 common.createSelfCorrectingClock 创建零漂移的自校正实时时钟。
    • 新增 common.createSelfCorrectingCountdown 创建零漂移的自校正倒计时器。
    • 完善文档说明。
  • 2025-05-08
    • 依赖集中在 pnpm-workspace.yaml - catalogs 统一管理。
    • 完善文档说明。
  • 2025-05-23
    • 增强脱敏函数(desensitize), 支持邮箱,银行卡号,姓名。
    • 完善文档说明。

📌 简介

ui-utils-kit 提供两大类常用功能:

  • 树形数据操作 构建树形结构、扁平化树、更新选中状态、查找相关节点等,帮助你高效管理和操作树状数据。

  • 海报制作 将 DOM 元素转换为图片(canvas),支持自动下载或返回 Blob 格式数据。

    针对跨域图片问题,内置 html2canvas proxy 解决方案。

  • 业务工具类函数 提供一些常用的业务工具函数,如 JSON 安全解析、敏感信息脱敏等。


📦 安装

使用 npm 安装:

npm install ui-utils-kit

使用 yarn 安装:

yarn add ui-utils-kit

🚀 使用方式

ui-utils-kit 的工具函数目前分为三大类:treebusinesscommon,支持两种导入方式:

方式一:

import{tree}from"ui-utils-kit";constresult=tree.buildTree(nodes);

方式二:

import{buildTree}from"ui-utils-kit";constresult=buildTree(nodes);

🔹 树形数据操作 (tree)

1. 构建树形结构

tree.buildTree 根据节点数据构建树形结构。

  • 参数:

    • nodes (Array<TreeNode>):包含 idpid 的节点数据数组。
    • preserveChildren (boolean,可选):是否保留原 children 属性。
  • 返回值:

    • Array<TreeNode>:构建后的树形结构数据。
  • 示例:

    import{buildTree}from'ui-utils-kit';constnodes=[{id: 1,pid: null,name: 'Root'},{id: 2,pid: 1,name: 'Child 1'},];consttree=buildTree(nodes);console.log(tree);

2. 扁平化树形结构

tree.treeToArr 将树形数据转换为扁平化数组,便于遍历与处理。

  • 参数:

    • tree (TreeNode):包含 idnamechildren的树形结构数据。
    • node (TreeNode):包含 idpid 的节点数据。
  • 返回值:

    • Array<TreeNode>:扁平化后的数组。
  • 示例:

    import{treeToArr}from'ui-utils-kit';consttree=[{id: 1,name: 'Root',children: [{id: 2,name: 'Child 1'}]}];constflatArray=treeToArr(tree);console.log(flatArray);

3. 更新树节点选中状态

tree.updateTreeCheckStatus 更新树中节点的选中状态(含子节点与父节点联动)。

  • 参数:

    • tree (TreeNode):包含 idnamechildren的树形结构数据。
  • 返回值:

    • Array<TreeNode>:更新后的节点数组。
  • 示例:

    import{updateTreeCheckStatus}from'ui-utils-kit';consttree=[{id: 1,name: 'Root',check: 'Unchecked',children: [{id: 2,name: 'Child 1',check: 'Unchecked'}]}];constselectedNodes=[{id: 2,name: 'Child 1',check: 'Checked'}];constupdatedTree=updateTreeCheckStatus(tree,selectedNodes);console.log(updatedTree);

4. 查找相关节点

tree.searchTreeWithRelations 根据关键词查找匹配节点,同时返回相关的父子关系。

  • 参数:

    • treeArr (TreeNode[]):树结构的数组,每个节点至少应包含 id, pid, name 属性,表示节点标识、父节点标识及节点名称。
    • keywords (string):用于匹配节点名称的关键词,支持模糊匹配(即 includes 匹配)。
    • mark (boolean):是否在匹配的节点上添加 isMatched 属性标记,默认值为 true。
  • 返回值:

    • Array<TreeNode>:匹配结果数组, 包含: 名称匹配的节点; 匹配节点的所有父节点; 匹配节点的所有子节点。 返回顺序为:父节点在前,子节点在后;同一层级节点顺序与原数组一致。。
  • 示例:

    import{searchTreeWithRelations}from'ui-utils-kit';consttree=[{id: 1,name: 'Root'},{id: 2,name: 'Child 1'},];constresults=searchTreeWithRelations(tree,'Child 1');console.log(results);

🎨 业务函数 (business)

1. DOM 转图片(例如生成海报)

captureElementAsImage 将 DOM 元素转换为图片(canvas),支持自动下载或返回 Blob 格式数据。

⚠️ 注意

如果截图元素中存在图片且图片源未设置允许跨域,那么需要后端提供图片转译服务( 代码可参考https://github.com/OFreshman/html2canvas-proxy

虽然个人提供了 https://h2c-proxy.netlify.app/api/ 服务(使用的是nitro + netlify)去测试处理跨域图片,但流量有限,谨慎使用!!!另外配置了proxy 必须设置useCORS:false,这两个属性时互斥的。

captureElementAsImage(element,{proxy: "后端的处理图片服务",useCORS: false})
  • 方法说明:

    • 参数:

      • element (HTMLElement | null):目标 DOM 元素。
      • canvasConfig (Partial<Html2canvasOptions>,可选):配置项,如 scalebackgroundColor 等。
      • outputOptions (OutputOptions,可选):输出设置,默认为自动下载图片。
    • 示例:

      import{captureElementAsImage}from'ui-utils-kit';constelement=document.getElementById('capture-area');captureElementAsImage(element,{scale: 2},{download: true,downloadName: 'screenshot'}).then(({ canvas, dataUrl, blob })=>{console.log('Canvas:',canvas);console.log('Data URL:',dataUrl);console.log('Blob:',blob);}).catch(err=>console.error(err));

! 小程序的话还是推荐canvas 去绘制,然后再结合 uni.canvasToTempFilePath 去转图片,优点是高度自定义。


🎨 公共通用函数 (common)

1. safeJsonParse(jsonString: string, defaultValue: T): [Error | null, T]

功能描述: 安全地解析 JSON 字符串,如果解析出错则返回默认值和错误对象。

参数

  • jsonString: string — 要解析的 JSON 格式字符串。

  • defaultValue: T — 当解析失败时返回的默认值,类型与期待的解析结果相同。

返回值[Error | null, T] — 一个元组:

  • 示例
import{safeJsonParse}from'ui-utils-kit';const[err,data]=safeJsonParse('{"foo": 42}',{foo: 0});if(err){// 处理解析错误}else{console.log(data.foo);// 42}

2. desensitize(value: string, type: "mobile" | "idcard" | "email" | "bankcard" | "name"): string

功能描述:对敏感信息(手机号或身份证号)进行脱敏处理,隐藏中间部分。

参数

  • value: string — 原始字符串,如手机号或身份证号。
  • type: "mobile" | "idcard" | "email" | "bankcard" | "name"
    • 默认保留首尾,中间脱敏部分
    • "mobile":脱敏手机号
    • "idcard":脱敏身份证号
    • "email":脱敏电子邮箱
    • "bankcard":脱敏银行卡号
    • "name":脱敏姓名

返回值string — 脱敏后字符串,如果输入非字符串则返回空字符串。

  • 示例
import{desensitize}from'ui-utils-kit';desensitize('13812345678','mobile');// 输出:138****5678desensitize('110105199001011234','idcard');// 输出:110105********1234desensitize("ethan.yin@openai.com","email");// => "e*********@openai.com"desensitize("a@domain.cn","email");// => "a@domain.cn" // 本地部分仅一个字符,无需替换desensitize("6227001234567890","bankcard");// => "**** **** **** 7890"desensitize("6227 0012 3456 7890","bankcard");// => "**** **** **** 7890"desensitize("张三","name");// => "张*"desensitize("张三丰","name");// => "张*丰"// 英文名(按单词脱敏)// - “John Doe” => “J**n D*e”// - “Al Li” => “A* L*”desensitize("John Doe","name");// 输出: J**n D*edesensitize("Al Li","name");// 输出: A* L*

3. Mutex 类

功能描述:模拟互斥锁机制,用于控制异步操作对共享资源的访问,确保同一时刻只有一个操作进入临界区。

以下是一些应用场景
  • 防止按钮重复点击:避免用户多次点击同一按钮导致重复网络请求或状态混乱。
  • 强制 API 调用顺序:确保一组异步接口按预期顺序依次执行,防止乱序带来的逻辑错误。
  • 多标签页 localStorage 访问:在多个浏览器标签或窗口同时操作同一 localStorage 时,避免数据竞争和丢失。
  • 分片上传(Chunked Upload):在大文件上传时,按顺序上传每个分片,确保断点续传或失败重试时不会错乱。
  • Web Worker 任务同步:在主线程与 Worker 线程之间同步访问共享内存(如 SharedArrayBuffer )时,保证原子性。
  • 示例
<template>
<view>
<button@click="onSubmit":disabled="isSubmitting">
{{ isSubmitting ? '提交中...' : '提交' }}
</button>
</view>
</template>
<script setup lang="ts">import { Mutex } from'ui-utils-kit'// 状态变量,无需在 setup 中 return,自动暴露给模板使用const isSubmitting =ref(false)// 创建一个互斥锁实例const submitMutex =newMutex()// 点击处理函数const onSubmit =async () => {// 获取锁:若已有操作在进行,则挂起后续调用awaitsubmitMutex.lock()try {isSubmitting.value=true// 模拟网络请求awaitnewPromise<void>(resolve=>setTimeout(resolve, 1500))uni.showToast({ title: '提交成功' }) } catch (err:any) {uni.showModal({ title: '错误', content: err.message }) } finally {isSubmitting.value=false// 释放锁,允许下一次点击submitMutex.unlock() }}</script>

4. createSelfCorrectingClock(interval?: number): SelfCorrectingClock

功能描述: 创建一个“零漂移”(self-correcting)实时时钟管理器。该管理器内部通过动态调节 setTimeout 延迟来消除长时间运行中的累积误差,并在浏览器标签切换或后台恢复后依然保持准确。

参数

  • interval?: number — 更新间隔(毫秒),可选,默认值为 1000

返回值SelfCorrectingClock — 一个对象,包含:

interfaceSelfCorrectingClock{/** 获取最新的当前时间戳(毫秒) */getCurrentTime(): number;/** 停止内部定时器,释放资源 */stop(): void;}
  • 示例
import{createSelfCorrectingClock}from'ui-utils-kit';// 创建一个每秒更新一次的自校正时钟constclock=createSelfCorrectingClock(1000);// 每 5 秒读取并打印一次当前时间戳constlogger=setInterval(()=>{console.log('当前时间戳:',clock.getCurrentTime());},5000);// …需要停止时,调用 stop() 并清理外部 loggersetTimeout(()=>{clock.stop();clearInterval(logger);console.log('时钟已停止');},30_000);

5. createSelfCorrectingCountdown(targetTimestamp: number, interval?: number): SelfCorrectingCountdown

功能描述: 创建一个“零漂移”自校正倒计时管理器。内部同样通过校正机制消除误差,到达目标时间时自动停止,并允许手动停止

参数

  • targetTimestamp: number — 倒计时结束的目标时间戳(毫秒)。

  • interval?: number — 更新间隔(毫秒),可选,默认值为 1000。

返回值SelfCorrectingCountdown — 一个对象,包含:

interfaceSelfCorrectingCountdown{/** 获取最新的剩余时间(毫秒) */getRemainingTime(): number;/** 停止内部定时器,释放资源 */stop(): void;}
  • 示例
import{createSelfCorrectingCountdown}from'ui-utils-kit';// 目标时间为当前时间后 10 秒consttarget=Date.now()+10_000;constcountdown=createSelfCorrectingCountdown(target,1000);// 每秒读取并打印一次剩余时间constlogger=setInterval(()=>{constleft=countdown.getRemainingTime();console.log('剩余时间(毫秒):',left);if(left===0){clearInterval(logger);console.log('倒计时结束');}},1000);// 如需提前取消倒计时// setTimeout(() => {// countdown.stop();// clearInterval(logger);// console.log('倒计时已手动停止');// }, 5000);

📜 类型定义

TreeNode 类型

typeTreeNode={id: string|number;pid: string|number|null;name: string;children?: TreeNode[];check?: 'Checked'|'Unchecked'|'HalfChecked';};

CheckStatus 枚举

exportconstCheckStatusMap={Unchecked: "0",HalfChecked: "1",Checked: "2"}asconst;exporttypeCheckStatus=typeofCheckStatusMap[keyoftypeofCheckStatusMap];

📜 许可证

About

一个偏业务前端工具函数库

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages