ui-utils-kit

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

GitHub Stars NPM Version NPM Downloads Bundle Size JSDocs License


📝 changelogs

TodoList

📌 简介

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


📦 安装

使用 npm 安装:

npm install ui-utils-kit

使用 yarn 安装:

yarn add ui-utils-kit

🚀 使用方式

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

方式一:

import { tree } from "ui-utils-kit";

const result = tree.buildTree(nodes);

方式二:

import { buildTree } from "ui-utils-kit";

const result = buildTree(nodes);

🔹 树形数据操作 (tree)

1. 构建树形结构

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

2. 扁平化树形结构

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

3. 更新树节点选中状态

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

4. 查找相关节点

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


🎨 业务函数 (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
})

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


🎨 公共通用函数 (common)

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

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

参数

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

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` — 脱敏后字符串,如果输入非字符串则返回空字符串。

- 示例
```typescript
import { desensitize } from 'ui-utils-kit';

desensitize('13812345678', 'mobile');  // 输出:138****5678
desensitize('110105199001011234', 'idcard'); // 输出:110105********1234

desensitize("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*e
desensitize("Al Li", "name"); // 输出: A* L*

3. Mutex 类

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

以下是一些应用场景
<template>
  <view>
    <button @click="onSubmit" :disabled="isSubmitting">
      
    </button>
  </view>
</template>

<script setup lang="ts">
import { Mutex } from 'ui-utils-kit'

// 状态变量,无需在 setup 中 return,自动暴露给模板使用
const isSubmitting = ref(false)
// 创建一个互斥锁实例
const submitMutex = new Mutex()

// 点击处理函数
const onSubmit = async () => {
  // 获取锁:若已有操作在进行,则挂起后续调用
  await submitMutex.lock()
  try {
    isSubmitting.value = true
    // 模拟网络请求
    await new Promise<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 延迟来消除长时间运行中的累积误差,并在浏览器标签切换或后台恢复后依然保持准确。

参数

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

interface SelfCorrectingClock {
  /** 获取最新的当前时间戳(毫秒) */
  getCurrentTime(): number;
  /** 停止内部定时器,释放资源 */
  stop(): void;
}

// 创建一个每秒更新一次的自校正时钟 const clock = createSelfCorrectingClock(1000); // 每 5 秒读取并打印一次当前时间戳 const logger = setInterval(() => { console.log(‘当前时间戳:’, clock.getCurrentTime()); }, 5000);

// …需要停止时,调用 stop() 并清理外部 logger setTimeout(() => { clock.stop(); clearInterval(logger); console.log(‘时钟已停止’); }, 30_000);


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

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

**参数**
- `targetTimestamp: number` — 倒计时结束的目标时间戳(毫秒)。

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

**返回值**
`SelfCorrectingCountdown` — 一个对象,包含:
```ts
interface SelfCorrectingCountdown {
  /** 获取最新的剩余时间(毫秒) */
  getRemainingTime(): number;
  /** 停止内部定时器,释放资源 */
  stop(): void;
}

// 目标时间为当前时间后 10 秒 const target = Date.now() + 10_000; const countdown = createSelfCorrectingCountdown(target, 1000);

// 每秒读取并打印一次剩余时间 const logger = setInterval(() => { const left = countdown.getRemainingTime(); console.log(‘剩余时间(毫秒):’, left); if (left === 0) { clearInterval(logger); console.log(‘倒计时结束’); } }, 1000);

// 如需提前取消倒计时 // setTimeout(() => { // countdown.stop(); // clearInterval(logger); // console.log(‘倒计时已手动停止’); // }, 5000);


---

## 📜 类型定义

### `TreeNode` 类型
```typescript
type TreeNode = {
  id: string | number;
  pid: string | number | null;
  name: string;
  children?: TreeNode[];
  check?: 'Checked' | 'Unchecked' | 'HalfChecked';
};

CheckStatus 枚举

export const CheckStatusMap = {
  Unchecked: "0",
  HalfChecked: "1",
  Checked: "2"
} as const;

export type CheckStatus = typeof CheckStatusMap[keyof typeof CheckStatusMap];

📜 许可证