@xiaojinquan/super-kit

一套闭源、可压缩混淆的多框架工具方法 + 组件 + 指令库(Vue2 / Vue3 / uni-app)。发布前请修改 name、author、repository。
1,851
Install
npm install @xiaojinquan/super-kit
Latest Version:0.0.20
Vue:2 · 3
License:Proprietary
Last Updated:Oct 16, 2026
Links: npm
Maintainer: xiaojinquan

使用文档 · @xiaojinquan/super-kit@0.0.20

1. 安装

npm install @xiaojinquan/super-kit
# 或
pnpm add @xiaojinquan/super-kit
  • 本库将 vue 声明为可选 peerDependency,不会强制安装。
  • 仅使用组件 / 指令时需要项目里存在 vue;纯工具方法(utils / env)无需 vue。
  • dayjs 为运行时依赖,消费方安装本包时自动拉取,不会重复打进 dist。

外部依赖说明

本库部分功能引用了外部依赖。这些依赖均不打包进 dist,以 import/require 形式保留、由消费方依赖树解析。使用前请按表确认运行环境已满足:

外部依赖 类型 被哪些功能引用 消费方是否需要安装 安装命令
dayjs 运行时依赖(dependencies) utils/dateTime 全部时间函数(见 §4.7) 否,安装本包时自动拉取 —(已随包安装)
vue 可选 peerDependency 组件(vue3/vue2/uniapp-*)与指令(directives/vue3/directives/vue2),见 §6、§7 是,使用组件 / 指令时需项目自带 vue npm install vue
node 内置模块(fs/path/crypto…) Node 运行时内置 node 子路径(fs / crypto / cli),见 §4.18 仅 Node 运行时,无需安装 —

构建侧保障(防止外部依赖被误打包):

  1. tsup.config.ts 与 scripts/vite-lib.mjs 均从 package.json 的 dependencies + peerDependencies 自动派生 external(含子路径正则),新增运行时包写进 package.json 即自动 external,无需改构建脚本。
  2. scripts/check-external.mjs(独立命令 pnpm check:external)扫描 dist 全部产物,若发现外部依赖被内联或存在未声明依赖泄漏则非零退出;已接入 pnpm build 末尾与 pnpm publish:npm 的混淆之后,作为发布闸门。

2. 入口总览

通过 package.json 的 exports 子路径按需引入,构建工具会自动解析 ESM / CJS:

子路径 内容
@xiaojinquan/super-kit 根入口 = 工具方法 + 环境解析器(importKit / detectEnv / resolveEntry / KIT_VERSION)
@xiaojinquan/super-kit/utils 框架无关工具方法(ESM + CJS + .d.ts)
@xiaojinquan/super-kit/env 环境探测 / 按环境引入解析器
@xiaojinquan/super-kit/node Node.js 专用工具(fs / crypto / cli,依赖 node 内置模块,仅 Node 运行时)
@xiaojinquan/super-kit/vue3 Vue3 组件 + 指令
@xiaojinquan/super-kit/vue2 Vue2 组件 + 指令
@xiaojinquan/super-kit/uniapp-vue3 uni-app Vue3 组件
@xiaojinquan/super-kit/uniapp-vue2 uni-app Vue2 组件
@xiaojinquan/super-kit/directives/vue3 Vue3 指令(v-click-outside / v-debounce / v-copy / v-back-top / v-expand-click / v-throttle / v-water-marker / v-draggable / v-long-press)
@xiaojinquan/super-kit/directives/vue2 Vue2 指令(v-click-outside / v-debounce / v-copy / v-back-top / v-expand-click / v-throttle / v-water-marker / v-draggable / v-long-press)
@xiaojinquan/super-kit/vue3/style.css 等 各组件框架编译后的样式(见 §6、§7)

3. 工具方法总览

import { formatNumber, debounce, copyText, formatDate } from "@xiaojinquan/super-kit/utils";
// 或(根入口已再导出 utils)
import { formatNumber, debounce, copyText } from "@xiaojinquan/super-kit";

全部工具方法按模块分组,均为框架无关、可 tree-shaking 的纯函数 / 类,模块之间也可互相引用(如 uniapp 依赖 parse 的 getFileUrlInfo 与 format 的 urlConversion)。

3.1 分类速查(全部导出)

模块 说明 全部导出
array 数组处理 swapArrayItems sum sort unique union intersect differenceSet toArray flatten group flatToTree treeToFlat clone deepClone dataStatisticsSync dataStatistics fuzzySearch multiFieldSearch
base 进制 / 压缩 convertRadix toDecimal fromDecimal lzwCompress lzwDecompress
calendar 农历 / 日历(全静态方法) Calendar(solar2lunar / lunar2solar / toGanZhiYear / toAstro / getAnimal / getTerm / lYearDays / leapMonth / leapDays / monthDays / solarDays / toGanZhi / toChinaMonth / toChinaDay)
canvas 画布绘制 calcAngle setText drawRoundRectPath fillRoundRect textPrewrap
chineseConverter 简繁转换(单例) ChineseConverter(getInstance / toSimplified / toTraditional / toSimplifieds / toTraditionals)
color 颜色处理 rgbToHex rgbaToHex hexToRgba randomColor getGradientStyle ThemeColor
dom DOM 操作 copyText(剪贴板复制)loadScript(加载单个外部 JS)loadScripts(顺序加载多个外部 JS)loadCSS(加载外部 CSS,同地址去重)
dateTime 时间处理(基于 dayjs) parseTime formatDate formatTimeToDateTime formatMsToDayHourMinSec isSamePeriod getTimeRange formatRelativeTime isWeekDay getDiffDays getDateRange getDaysOfPeriod isLeapYear getDayOfPeriod getWeekOfPeriod getDateRangeBetween calcExpirationDate
device 设备 / 系统检测(仅浏览器) getSystem(基于 navigator.userAgent 识别 iOS / Android / HarmonyOS / 桌面)browserType(基于 navigator.userAgent 识别 IE / Edge / Firefox / Opera / Safari / Chrome)isWechat(是否处于微信内置浏览器)getWechatVersion(微信版本号,如 "7.0.21",非微信返回 null)
desensitize 脱敏 maskString desensitizePhone desensitizeEmail desensitizeIdCard desensitizeName desensitizeBankCard desensitizePhoneLandline
format 格式化 formatFileSize formatPercent formatPhone formatBankCard formatIdCard formatDecimal formatNumberShort formatNumber formatCompact parseNumber truncateDecimal roundDecimal formatDistance numberToChinese amountToChinese urlConversion
function 函数增强 debounce throttle throttleTimer
http 网络请求 ajax(XHR Promise 化)+ AjaxError(错误分类:network/timeout/abort/http/parse)+ fetchHttp(fetch 封装)。readFileContent 已移入 file(本质是「GET 文本 + 可选 \uXXXX 解码」,归属资源读取语义),decodeUnicodeEscapes 已移入 string(纯字符串工具)。
file 文件 / 图像 / 媒体处理(仅浏览器) imageToBase64(URL → base64 dataURL)base64ImgDownloadFile(dataURL → 下载)dataUrlToBlob(dataURL → Blob,Node v16+ 亦可)downloadBlob(Blob / 文件流 → 下载)downloadTable(对象数组 → TSV / CSV)loadAudio(音频加载 → 可播放 HTMLAudioElement)captureFrame(视频 → 截帧,正确的 loadedmetadata → currentTime → seeked 流程)readFileContent(GET 文本读取 + 可选 \uXXXX 解码,依赖 http/fetchHttp + string/decodeUnicodeEscapes,自 http 模块移入)
location 经纬度(全静态方法) Location(getDistance / getDistanceVincenty / polymerization / getLocationCenter / gcj02towgs84 / wgs84togcj02 / bd09togcj02 / gcj02tobd09 / getPolygonArea / isPointInPolygon)
parse 解析 getInfoByIdCard getPasswordStrength getFileUrlInfo extractRichText
random 随机 generateCaptcha randomInt randomFloat randomIntExclude randomPick shuffle randomBoolean uuidv4
string 字符串 escapeHtml unescapeHtml zeroWidthTrim byteLength camelToSeparated separatedToCamel queryString queryObject trim convertCase decodeUnicodeEscapes(自原 http 模块移入,解码 \uXXXX 转义;命名如实反映行为)
storage 浏览器存储(cookie / localStorage / sessionStorage) setCookie getCookie getCookies setCookies removeCookie clearCookies setLocalStorage getLocalStorage getAllLocalStorage getLocalStorageKeys removeLocalStorage clearLocalStorage setSessionStorage getSessionStorage getAllSessionStorage getSessionStorageKeys removeSessionStorage clearSessionStorage LocalStorageWatcher localStorageWatcher SessionStorageWatcher sessionStorageWatcher CookieWatcher cookieWatcher
validator 校验 isString isNumber isBoolean isFunction isNull isUndefined isNil isPlainObject isArray isDate isRegExp isError isSymbol isPromise isSet isFile isBlob isFalse isTrue isEmpty isNotBlank isCamelCase isHasZeroWidthChars isSeparated isValidIdCard Validator 类
uniapp uni-app / 小程序 API 封装 showToast chooseMessageFile chooseMedia previewMedia downloadFile openDocument filePreviewShare saveImageToPhotosAlbum chooseLocation getLocation updateApplet addPhoneContact getLoginCode getScreenBrightness getDomInfo getImageInfo getSystemInfoSync rpxToPx pxToRpx backRefresh storageWatcher(StorageWatcher 全局唯一单例,可监听本地缓存事件中心)
node/fs 文件系统(仅 Node) ensureDir readJsonFile readJsonFileSync writeJsonFile writeJsonFileSync tempFilePath(引用 utils.uuidv4)
node/crypto 哈希 / 令牌(仅 Node) md5 sha256 randomHex randomToken uuidv4(再导出 utils)
node/cli 命令行解析(仅 Node) parseArgs formatArgHelp generateRunId(引用 utils.uuidv4)

4. 各模块完整 API 参考

4.1 array — 数组处理

函数 签名 说明
swapArrayItems <T>(arr: T[], index1: number, index2: number, options?: SwapOptions): T[] 交换两个位置元素。options.mutate 默认 false(返回新数组);options.throwOnInvalid 默认 false(越界时返回原数组并告警)
sum <T>(data: T[], key?: keyof T): number 求和;传入 key 则对对象该属性求和,自动过滤非数值
sort <T>(data: T[], key?: keyof T, order?: SortOrder): T[] 排序,order 为 'asc' | 'desc',默认 'asc',不修改原数组
unique <T>(arr: T[], key?: keyof T): T[] 去重;传 key 按对象属性去重
union <T>(a: T[], b: T[]): T[] 并集(去重)
intersect <T>(a: T[], b: T[]): T[] 交集
differenceSet <T>(arrOne: T[], arrTwo: T[]): T[] 对称差集
toArray <T>(arrayLike: ArrayLike<T> | Iterable<T>): T[] 类数组 / 可迭代对象转真数组
flatten (arr: any[], depth?: number): T[] 扁平化,depth 默认 Infinity
group <T extends Record<string, any>>(arr: T[], key: keyof T): GroupResult<T>[] 按属性分组,返回 [{ name, children }]
flatToTree <T extends Record<string, any>>(data: T[], relation?: [string,string], children?: string, hasChildren?: string): T[] 平铺数组转树形,relation 默认 ['pid','id']
treeToFlat <T extends Record<string, any>>(data: T[], relation?: [string,string], children?: string, hasChildren?: string): T[] 树形转平铺数组
clone <T>(target: T): T 浅拷贝(数组 / 对象一层)
deepClone <T>(value: T, cache?: Map<any,any>): T 深拷贝,支持循环引用、Date / RegExp
dataStatisticsSync <T>(array: T[], generateKey: (item: T) => string | number | symbol | null | undefined): StatisticsResult 同步分组计数,返回 { [key]: count }
dataStatistics <T>(array: T[], generateKey: (item: T) => ... | Promise<...>): Promise<StatisticsResult> 异步版,generateKey 可返回 Promise
fuzzySearch (str: unknown, pattern: string, options?: FuzzySearchOptions): boolean SQL LIKE 模糊匹配(% 任意多字符、_ 单字符);options.caseSensitive / exactMatch 默认 false
multiFieldSearch <T extends Record<string, any>>(array: T[], fields: (keyof T)[], pattern: string, options?: MultiFieldSearchOptions): T[] 多字段模糊查询;options.matchAllFields 默认 false、fieldMissing 默认 'skip'
import {
  unique,
  flatten,
  group,
  flatToTree,
  treeToFlat,
  deepClone,
  fuzzySearch,
} from "@xiaojinquan/super-kit/utils";
unique([1, 1, 2, 3]); // [1, 2, 3]
flatten([1, [2, [3]]]); // [1, 2, 3]
group([{ t: "A" }, { t: "A" }], "t"); // [{ name: 'A', children: [...] }]
flatToTree(list, ["pid", "id"]); // 树形数组
treeToFlat(tree, ["pid", "id"], "children");
deepClone(obj); // 深拷贝(带循环引用缓存)
fuzzySearch("hello", "h%o"); // true

4.2 base — 进制 / 压缩

函数 签名 说明
convertRadix (num: string | number, fromRadix?: Radix, toRadix?: Radix, options?: RadixConvertOptions): string 2–36 进制互转;options.useBigInt / allowPrefix(默认 true,识别 0x/0b/0o)/ outputPrefix
toDecimal (num: string, fromRadix?: Radix): number 指定进制字符串转十进制数字
fromDecimal (num: number | string, toRadix?: Radix): string 数字转指定进制字符串(BigInt,避免精度丢失)
lzwCompress (input: string, options?: LzwOptions): string LZW 压缩;options.maxDictSize 默认 4096、outputBase64 默认 false
lzwDecompress (input: string, options?: LzwOptions): string LZW 解压;options.autoDetectBase64 默认 true
import {
  convertRadix,
  toDecimal,
  fromDecimal,
  lzwCompress,
  lzwDecompress,
} from "@xiaojinquan/super-kit/utils";
convertRadix("110", 2, 10); // '6'
convertRadix("AF", 16, 10); // '175'
convertRadix("175", 10, 16); // 'af'
toDecimal("ff", 16); // 255
fromDecimal(255, 16); // 'ff'
lzwCompress("repeat repeat"); // 压缩字符串(可 outputBase64: true)
lzwDecompress(compressed); // 还原

4.3 calendar — 农历 / 日历(全静态方法,无需实例化)

import { Calendar } from "@xiaojinquan/super-kit/utils";
静态方法 签名 返回 说明
solar2lunar (y?: number, m?: number, d?: number): LunarResult | -1 农历信息对象 公历 → 农历;不传参取当天;非法返回 -1
lunar2solar (y: number, m: number, d: number, isLeapMonth?: boolean): LunarResult | -1 农历信息对象 农历 → 公历;非法返回 -1
toGanZhiYear (lYear: number): string 干支纪年,如 '甲辰'
toAstro (cMonth: number, cDay: number): string 星座,如 '摩羯座'
toGanZhi (offset: number): string 干支(按偏移)
getTerm (y: number, n: number): number 第 n 个节气(公历日),n:1–24
toChinaMonth (m: number): string | number 农历月中文,如 '正月'
toChinaDay (d: number): string 农历日中文,如 '廿一'
getAnimal (y: number): string 生肖,如 '龙'
lYearDays (y: number): number 农历某年总天数
leapMonth (y: number): number 闰月月份,无则返回 0
leapDays (y: number): number 闰月天数
monthDays (y: number, m: number): number 农历某月天数
solarDays (y: number, m: number): number 公历某月天数

LunarResult 含:lYear lMonth lDay Animal IMonthCn IDayCn cYear cMonth cDay gzYear gzMonth gzDay isToday isLeap nWeek ncWeek isTerm Term astro。

Calendar.solar2lunar(2026, 1, 1); // { lYear: 2025, IMonthCn: '腊月', ... }
Calendar.lunar2solar(2026, 1, 1); // 公历信息对象
Calendar.toGanZhiYear(2026); // '丙午'
Calendar.getAnimal(2026); // '马'

4.4 canvas — 画布绘制(传入 CanvasRenderingContext2D)

函数 签名 说明
calcAngle (angle: number, width: number, height: number, startX?: number, startY?: number): [number, number, number, number] 计算沿角度方向的线性渐变起止坐标 [x0,y0,x1,y1]
setText (ctx, color?, font?, textAlign?, textBaseline?): void 设置文本样式(默认 #999999 / 38px PingFangSC-Medium, PingFang SC / left / top)
drawRoundRectPath (ctx, width: number, height: number, radius?: number): void 仅构建圆角矩形路径(不填充)
fillRoundRect (ctx, x, y, width, height, radius?, fillColor?): void 绘制并填充圆角矩形(自动 save/restore)
textPrewrap (ctx, content, drawX, drawY, fontSize, lineHeight, lineMaxWidth, lineNum, indent?): void 自动换行绘制文本,lineNum 超出截断加 ...
import { textPrewrap, fillRoundRect, drawRoundRectPath } from "@xiaojinquan/super-kit/utils";
const ctx = canvas.getContext("2d")!;
fillRoundRect(ctx, 10, 10, 200, 100, 15, "rgba(0,150,255,0.8)");
textPrewrap(ctx, "长文本…", 10, 10, 16, 24, 200, 3, 20);

4.5 chineseConverter — 简繁转换(单例)

import { ChineseConverter } from "@xiaojinquan/super-kit/utils";
const cv = ChineseConverter.getInstance(); // 全局唯一实例
方法 签名 说明
getInstance (): ChineseConverter 获取单例
toSimplified (char: string): string 单个繁体字 → 简体(非单字返回 '')
toTraditional (char: string): string 单个简体字 → 繁体
toSimplifieds (str: string): string 繁体字符串 → 简体
toTraditionals (str: string): string 简体字符串 → 繁体
ChineseConverter.getInstance().toSimplifieds("繁體"); // '繁体'
ChineseConverter.getInstance().toTraditionals("简体"); // '簡體'

4.6 color — 颜色处理

函数 签名 返回 / 说明
rgbToHex (r: number|string, g: number|string, b: number|string): HexColor 如 '#ff0000',越界自动裁剪
rgbaToHex (r, g, b, a?, bgR?, bgG?, bgB?): HexColor 半透明叠加背景色后转不透明 hex(默认白底)
hexToRgba (hex: string, alpha?: number, asString?: boolean): RGBA | string | null 支持 #rgb/#rrggbb;asString 返回 'rgba(...)';非法返回 null
randomColor (options?: RandomColorOptions): string options.format(hex/rgb/rgba/hsl)、alpha、brightness(light/dark/any)
getGradientStyle (str: string, params?: GradientStyleParams): GradientStyleResult 按字符串稳定哈希生成渐变样式;相同字符串恒定同色。可配 angle/type(linear/radial)/radialShape(circle/ellipse)/gradients;返回含 style.backgroundImage、所选 index 与归一化配置
ThemeColor new ThemeColor(imgUrl, callBack?, options?): ThemeColor 浏览器 / H5 专用:从图片提取出现次数最多的主色调。结果经回调或 await themeColor.ready 获取({ shrinkUrl, themeColor, rgba });跨域图片需 CORS 头;失败回退白色
import { rgbToHex, rgbaToHex, hexToRgba, randomColor, getGradientStyle, ThemeColor } from "@xiaojinquan/super-kit/utils";
rgbToHex(255, 0, 0); // '#ff0000'
rgbaToHex(255, 0, 0, 0.5); // '#ff8080'
hexToRgba("#ff0000"); // { r:255, g:0, b:0, a:1 }
hexToRgba("#ff0000", 0.5, true); // 'rgba(255,0,0,0.5)'
randomColor({ format: "hex", brightness: "light" });

// 文字渐变:相同字符串恒定同一渐变
const g = getGradientStyle("Hello World");
// <span style={g.style}>Hello World</span>
getGradientStyle("Custom", { angle: 90, type: "radial", radialShape: "circle" });

// 图片主色提取(浏览器 / H5)
const tc = new ThemeColor("https://example.com/cover.jpg");
const { shrinkUrl, themeColor, rgba } = await tc.ready;

4.7 dateTime — 时间处理(基于 dayjs)

⚠️ 依赖 dayjs:本模块全部时间函数基于 dayjs 及其 weekOfYear / dayOfYear 插件实现。dayjs 为运行时依赖(已写入 package.json 的 dependencies),安装本包时自动拉取,无需另行安装。

函数 签名 说明
parseTime (time: TimeInput): Dayjs | null 解析时间,无效返回 null
formatDate (time: TimeInput, formatStr?: string): string 默认 'YYYY-MM-DD HH:mm:ss',无效返回 ''
formatTimeToDateTime (time: TimeInput): string 同年省略年份,跨年显示完整;同日带 HH:mm
formatMsToDayHourMinSec (ms: number): string 1天2时3分4秒;负数 / NaN 返回 ''
isSamePeriod (time1, time2, unit: PeriodUnit): boolean day/week/month/year 是否同期
getTimeRange (unit: PeriodUnit, time?: TimeInput, weekStartsOn?: WeekStartDay): [number, number] 时段起止时间戳 [startMs, endMs];weekStartsOn:0=周日,1=周一
formatRelativeTime (time: TimeInput, baseTime?): string 中文相对时间(刚刚 / 分钟前 / 昨天 / X天前 / X个月前 / X年前;未来时间返回日期)
isWeekDay (time: TimeInput): boolean 是否工作日(周一至周五)
getDiffDays (time1, time2): number 相差天数(绝对值向下取整)
getDateRange (unit: PeriodUnit, time: TimeInput, len?: number, direction?: 1|2|3): string[] 前后日期数组;direction:1前 2后 3前后含基准
getDaysOfPeriod (unit: MonthYearUnit, time?): number 当月 / 当年天数
isLeapYear (year: YearInput): boolean 是否闰年
getDayOfPeriod (unit: WeekMonthYearUnit, time?): number 当年第几天 / 第几月 / 第几周
getWeekOfPeriod (unit: MonthYearUnit, time?): number 该月 / 该年第几周
getDateRangeBetween (unit: PeriodUnit, time1, time2): DateRangeItem[] 两日期间按单位划分的时间点数组 [{ timestamp, label }]
calcExpirationDate (startTime: TimeInput, years, months, days): number 截止日期时间戳;负数参数返回 0
import {
  formatDate,
  formatRelativeTime,
  getTimeRange,
  isLeapYear,
} from "@xiaojinquan/super-kit/utils";
formatDate(1735689600000); // '2026-01-01 00:00:00'
formatDate("2026-08-20", "YYYY-MM-DD"); // '2026-08-20'
formatRelativeTime("2026-08-19 12:00", "2026-08-20 12:00"); // '昨天'
const [start, end] = getTimeRange("month"); // 本月起止时间戳
isLeapYear(2024); // true

4.8 desensitize — 脱敏

函数 签名 说明
maskString (str: StringInput, start?: number, end?: number, mask?: string, maskLen?: number): string 通用脱敏,保留前 start、后 end 位
desensitizePhone (phone): string 手机号:138****5678(前3后4)
desensitizeEmail (email): string 邮箱:本地保留首字符,如 t***@example.com
desensitizeIdCard (id): string 身份证:前6后4,110101********1234
desensitizeName (name): string 姓名:张** / 张*三
desensitizeBankCard (card): string 银行卡:前4后4
desensitizePhoneLandline (phone): string 固定电话:保留后4位,区号不脱敏
import {
  desensitizePhone,
  desensitizeName,
  desensitizeIdCard,
} from "@xiaojinquan/super-kit/utils";
desensitizePhone("13812345678"); // '138****5678'
desensitizeName("张三"); // '张**'
desensitizeIdCard("110101199001011234"); // '110101********1234'

4.9 dom — DOM 操作

函数 签名 说明
copyText (text: string): Promise<boolean> 复制文本到剪贴板;优先 navigator.clipboard,降级 execCommand('copy');返回是否成功
loadScript (url: string, callback?: () => void): Promise<void> 动态加载单个外部 JS(注入 <script> 到 <head>);加载成功 resolve、失败 reject;兼容回调式用法
loadScripts (urls: string[], callback?: () => void): Promise<void> 顺序加载多个外部 JS(前完成再加载下一个);全部完成 resolve、任一失败 reject;兼容回调式用法
loadCSS (url: string, options?: LoadCssOptions): Promise<void> 动态加载外部 CSS(注入 <link rel="stylesheet">);同地址自动去重;options.media 支持媒体查询
import { copyText, loadScript, loadScripts, loadCSS } from "@xiaojinquan/super-kit/utils";
const ok = await copyText("hello");
if (ok) console.log("已复制");
// 指令 v-copy 内部即调用 copyText

await loadScript("/sdk.js");                 // 推荐:Promise 式
loadScript("/sdk.js", () => console.log("loaded")); // 兼容:回调式

await loadScripts(["/a.js", "/b.js", "/c.js"]); // 依次加载 a → b → c

await loadCSS("/theme.css");
await loadCSS("/print.css", { media: "print" });

4.10 format — 格式化

函数 签名 说明
formatFileSize (bytes: NumericInput, decimals?: number): string 1.23 MB;0 → '0 B'
formatPercent (num: NumericInput, decimals?, includeSign?): string 12.34%(0.1234 → 12.34%)
formatPhone (phone: NumericInput, separator?: string): string 138-1234-5678
formatBankCard (card: NumericInput, separator?): string 每4位一组,6222 0000 1234 5678
formatIdCard (id: NumericInput, separator?): string 110101 19900307 1234
formatDecimal (num: NumericInput, decimals?): string 保留小数(不补千分位)
formatNumberShort (num: NumericString): string <10万 原样,k / w 单位缩写
formatNumber (num: unknown, options?: FormatNumberOptions): string 千分位格式化;options:decimals/forceDecimals/thousandsSeparator/decimalSeparator/currency/currencyPosition/negativeFormat
formatCompact (num: unknown, decimals?): string 紧凑显示 1.2k / 3.5M / 987.7M
parseNumber (str: unknown, options?: ParseNumberOptions): number 解析格式化字符串为数字;非法返回 NaN;options.thousandsSeparator/decimalSeparator
truncateDecimal (num: number, fixed?): number 截断(非四舍五入)
roundDecimal (num: number, fixed?): number 四舍五入
formatDistance (meters: unknown, options?: DistanceFormatOptions): string 米 / 公里自适应;options:unit/nearThreshold/prefix/suffix/decimals/showUnit
numberToChinese (num: unknown, options?: ChineseNumberOptions): string 数字转中文;options.style(lower/upper)、useUnits/handleDecimal/simplifyTen
amountToChinese (amount: unknown, options?: CurrencyChineseOptions): string 金额转中文大写;options.includeWhole/negativePrefix
urlConversion (path: string): string http://→https://、自动补 // 协议、已是 https 原样返回
import {
  formatNumber,
  amountToChinese,
  urlConversion,
  formatPhone,
  numberToChinese,
} from "@xiaojinquan/super-kit/utils";
formatNumber(1234567.89); // '1,234,567.89'
formatNumber(1234567.89, { currency: "¥" }); // '¥1,234,567.89'
amountToChinese(1234.56); // '壹仟贰佰叁拾肆元伍角陆分'
urlConversion("//a.com/b"); // 'https://a.com/b'
formatPhone("13812345678"); // '138-1234-5678'
numberToChinese(1234); // '一千二百三十四'

4.11 function — 函数增强

函数 签名 说明
debounce <T extends Fn>(func: T, delay: number): DebouncedFunction<T> 防抖(最后一次触发后延迟执行);返回函数带 .cancel()
throttle <T extends Fn>(func: T, interval: number): DebouncedFunction<T> 时间戳节流(首次立即执行);.cancel() 仅为接口一致
throttleTimer <T extends Fn>(func: T, interval: number): DebouncedFunction<T> 定时器节流(首次延迟、末次执行);.cancel() 可取消待执行任务
import { debounce, throttle, throttleTimer } from "@xiaojinquan/super-kit/utils";
const search = debounce((v: string) => console.log(v), 300);
search.cancel(); // 取消待执行任务
const scroll = throttle(() => {}, 200);
const click = throttleTimer(() => {}, 1000);

4.12 location — 经纬度(全静态方法,无需实例化)

import { Location } from "@xiaojinquan/super-kit/utils";
静态方法 签名 说明
getDistance (lng1, lat1, lng2, lat2): number 两点球面距离(米,Haversine)
getDistanceVincenty (lng1, lat1, lng2, lat2): number Vincenty 测地线距离(更精确,不收敛回退 Haversine)
polymerization <T extends Point>(data: T[], threshold?: number): T[][] 坐标聚合(并查集),threshold 默认 100 米
getLocationCenter <T extends Point>(points: T[]): T | null 多边形中心点(平均坐标)
gcj02towgs84 (lng, lat): Point GCJ-02(火星)→ WGS-84
wgs84togcj02 (lng, lat): Point WGS-84 → GCJ-02
bd09togcj02 (bdLon, bdLat): Point BD-09(百度)→ GCJ-02
gcj02tobd09 (lng, lat): Point GCJ-02 → BD-09
getPolygonArea (points: Point[]): number 多边形面积(平方米)
isPointInPolygon (point: Point, polygon: Point[]): boolean 射线法判断点是否在多边形内

Point = { longitude: number; latitude: number }。

Location.getDistance(116.4, 39.9, 121.47, 31.23); // 两点球面距离(米)
Location.wgs84togcj02(116.4, 39.9); // 坐标转换

4.13 parse — 解析

函数 签名 返回 说明
getInfoByIdCard (idCard: unknown): IdCardInfo | null { birthday, gender, age } 解析 18 位身份证;非法返回 null
getPasswordStrength (password: unknown, minLength?: number, specialChars?: RegExp): PasswordStrengthResult { level, description, score, length, meetsMinLength } 密码强度(数字/小写/大写/特殊各 1 分)
getFileUrlInfo (url: string): FileUrlInfo | undefined { fullName, name, suffix, type } 从 URL 提取文件信息;type:1图 2视频 3文档 4音频;不支持返回 undefined
extractRichText (html: string, options?: ExtractOptions): RichTextExtractResult { text, images, videos, audios, iframes, links, otherMedia } 富文本提取纯文本与媒体 URL;options 可逐项开关提取
import {
  getInfoByIdCard,
  getPasswordStrength,
  getFileUrlInfo,
  extractRichText,
} from "@xiaojinquan/super-kit/utils";
getInfoByIdCard("110101199003071234"); // { birthday:'1990-03-07', gender:'男', age:36 }
getPasswordStrength("Abc123_"); // { level:4, description:'极强', score:4, length:7, meetsMinLength:true }
getFileUrlInfo("https://x/y.jpg"); // { fullName:'y.jpg', name:'y', suffix:'jpg', type:'1' }

4.14 random — 随机

函数 签名 说明
generateCaptcha (digit?: number, options?: GenerateCaptchaOptions): string 验证码;digit 默认 6;options.charSet(number/letter/alphanumeric)、case(upper/lower/mixed)、excludeAmbiguous 默认 true
randomInt (a: number, b?: number, options?: RandomOptions): number 随机整数;单参 [0,a];options.inclusive 默认 true、validateRange 默认 true(自动交换 min/max)
randomFloat (a: number, b?: number): number 随机浮点;单参 [0,a]
randomIntExclude (min: number, max: number, exclude: number[]): number 排除指定数字的随机整数(递归重取)
randomPick <T>(arr: T[]): T | undefined 随机取一个元素
shuffle <T>(arr: T[]): T[] Fisher-Yates 洗牌(返回新数组)
randomBoolean (probability?: number): boolean true 概率,默认 0.5
uuidv4 (): string UUID v4(优先 crypto.randomUUID())
import { uuidv4, randomInt, generateCaptcha, shuffle } from "@xiaojinquan/super-kit/utils";
uuidv4(); // '3b1f8c7e-2a9d-4c5b-...'
randomInt(1, 10); // 1~10
generateCaptcha(6, { charSet: "number" }); // '372915'
shuffle([1, 2, 3, 4, 5]);

4.15 string — 字符串

函数 签名 说明
escapeHtml (str: unknown, options?: EscapeHtmlOptions): unknown HTML 转义;options.escapeSpace/escapeDoubleQuote(默认 true)/escapeSingleQuote
unescapeHtml (str: unknown): unknown HTML 反转义
zeroWidthTrim (str: unknown, options?: ZeroWidthOptions): unknown 移除零宽字符;options.customRegex/debug
byteLength (str: unknown): number UTF-8 字节长度(中文 3、emoji 4)
camelToSeparated (str: unknown, separator?: string): unknown 驼峰 → 分隔符(camelCase→camel_case)
separatedToCamel (str: unknown, separator?, capitalizeFirst?): unknown 分隔符 → 驼峰;capitalizeFirst 默认 false(大驼峰)
queryString (obj: Record<string, any>): string 对象 → 查询串(过滤 null/undefined,支持数组)
queryObject (str: string): Record<string, string> 查询串 → 对象(重复键取后者)
trim (str: unknown, mode?: TrimMode): unknown mode: 'all'/'start'/'end'/'extra'(合并多余空格)/'both'(默认)
convertCase (str: unknown, mode?: CaseMode): unknown mode: 'upper'(默认)/'lower'/'capitalize'/'uncapitalize'/'swap'
decodeUnicodeEscapes (input: string): string 解码 \uXXXX 转义序列(自原 http 模块移入);用显式正则 + String.fromCharCode,无废弃 unescape
import {
  escapeHtml,
  camelToSeparated,
  queryObject,
  trim,
  convertCase,
  decodeUnicodeEscapes,
} from "@xiaojinquan/super-kit/utils";
escapeHtml("<a>"); // '&lt;a&gt;'
camelToSeparated("fooBar"); // 'foo_bar'
queryObject("?a=1&b=2"); // { a:'1', b:'2' }
trim("  a   b  ", "extra"); // 'a b'
convertCase("hello world", "capitalize"); // 'Hello World'
decodeUnicodeEscapes("\\u4F60\\u597D"); // '你好'

4.16 storage — 浏览器存储(cookie / localStorage / sessionStorage)

仅浏览器 / H5 可用(依赖 DOM document / window.localStorage / window.sessionStorage);Node / uni-app 小程序原生端不可用。cookie 读写的编解码复用 string 模块的 queryObject(解析 document.cookie),与 queryString 风格一致。提供三个可监听缓存类(API 风格一致,互相对称):

  • LocalStorageWatcher — 监听 localStorage(支持跨标签页同步,原生 storage 事件)
  • SessionStorageWatcher — 监听 sessionStorage(仅同标签页,无原生事件)
  • CookieWatcher — 监听 cookie(基于轮询 diff,默认 500ms,能捕获任意来源写入)
函数 / 类 签名 说明
setCookie (name: string, value: string, options?: CookieOptions): void 设置单个 cookie(值自动 encode);options:expires(天)/maxAge(秒)/path/domain/secure/sameSite
setCookies (cookies: Record<string, string>, options?: CookieOptions): void 批量设置 cookie(统一 options)
getCookie (name: string): string 读单个 cookie(值自动 decode);未命中返回 ""
getCookies (): Record<string, string> 读全部 cookie(复用 queryObject)
removeCookie (name: string, options?: CookieOptions): void 删除单个 cookie(max-age=-1)
clearCookies (): void 清空全部 cookie
setLocalStorage (key: string, value: unknown): void 写 localStorage(JSON.stringify)
getLocalStorage <T>(key: string): T | null 读 localStorage(JSON.parse,失败/缺失返回 null)
getAllLocalStorage (): Record<string, unknown> 读全部 localStorage
getLocalStorageKeys (): string[] 读 localStorage 全部 key
removeLocalStorage (key: string): void 删 localStorage 指定 key
clearLocalStorage (): void 清空 localStorage
setSessionStorage (key: string, value: unknown): void 写 sessionStorage(JSON.stringify)
getSessionStorage <T>(key: string): T | null 读 sessionStorage
getAllSessionStorage (): Record<string, unknown> 读全部 sessionStorage
getSessionStorageKeys (): string[] 读 sessionStorage 全部 key
removeSessionStorage (key: string): void 删 sessionStorage 指定 key
clearSessionStorage (): void 清空 sessionStorage
LocalStorageWatcher new LocalStorageWatcher(storage?: Storage) 可监听 localStorage;构造可传任意 Storage 实例;跨标签页通过原生 storage 事件同步;同标签页由 setStorageWatch/removeStorageWatch/clearStorageWatch 触发;提供 watchStorage/unWatchStorage/hasPendingEvent/destroy
localStorageWatcher LocalStorageWatcher 全局唯一单例(推荐直接 import 使用)
SessionStorageWatcher new SessionStorageWatcher(storage?: Storage) 可监听 sessionStorage;不支持跨标签页(storage 事件仅对 localStorage 触发);同标签页由内部桥接函数触发;方法签名与 LocalStorageWatcher 一致
sessionStorageWatcher SessionStorageWatcher 全局唯一单例(推荐直接 import 使用)
CookieWatcher new CookieWatcher(options?: CookieWatcherOptions) 可监听 cookie;基于轮询 diff(默认 500ms,最小 50ms);能捕获任意来源写入(直接 JS / Set-Cookie 响应头 / 第三方脚本);不提供 setCookieWatch 等桥接函数;提供 watchCookie/unWatchCookie/pause/resume/isRunning/hasPendingEvent/destroy
cookieWatcher CookieWatcherSingleton(懒加载) 全局单例;仅在首次 watchCookie 时才启动轮询定时器——若业务侧从未调用 watchCookie,不会产生任何轮询开销
import {
  setCookie, getCookie, getCookies,
  setLocalStorage, getLocalStorage,
  setSessionStorage, getSessionStorage,
  LocalStorageWatcher, localStorageWatcher,
  SessionStorageWatcher, sessionStorageWatcher,
  CookieWatcher, cookieWatcher,
} from "@xiaojinquan/super-kit/utils";

// cookie
setCookie("token", "abc", { expires: 7, sameSite: "Lax" });
getCookie("token"); // 'abc'
getCookies();       // { token: 'abc', ... }

// localStorage / sessionStorage(自动 JSON 序列化 / 反序列化)
setLocalStorage("user", { id: 1, name: "Tom" });
getLocalStorage("user"); // { id: 1, name: 'Tom' }
setSessionStorage("draft", { text: "hello" });
getSessionStorage("draft"); // { text: 'hello' }

// LocalStorageWatcher:跨标签页同步 + 同标签页桥接
const off = localStorageWatcher.watchStorage("token", (newVal, oldVal) => {
  console.log(newVal, oldVal);
});
localStorageWatcher.setStorageWatch("token", "abc123"); // 触发上面的回调
off(); // 取消监听

// SessionStorageWatcher:仅同标签页同步
sessionStorageWatcher.watchStorage("draft", (newVal) => console.log(newVal));
sessionStorageWatcher.setStorageWatch("draft", { title: "未命名" });

// CookieWatcher:轮询 diff(≤500ms 内触发)
cookieWatcher.watchCookie("token", (newVal, oldVal) => {
  console.log("token 变化:", newVal, oldVal);
});
setCookie("token", "new-value"); // 下一个 tick 内触发回调

// 自定义轮询间隔
const cw = new CookieWatcher({ intervalMs: 1000 });

4.17 uniapp — uni-app / 小程序 API 封装

对 uni.* 回调式 API 做 Promise 化 / 对象传参 / 字段对齐官方命名 封装,不依赖 @dcloudio/uni-app 类型包(内部维护局部 Uni 子集类型 + getUni() 运行时访问,非 uni 环境抛明确错误)。入参均为对象、字段一一对应官方命名;文件类方法支持 [key: string]: unknown 透传索引签名(官方新增字段无需改库)。

函数 签名 说明
showToast (params?: string | ShowToastOptions): void 轻提示;字符串或对象传参;默认 icon:'none';先 hideLoading() 再延迟 100ms 显示
chooseMessageFile (params?: Partial<ChooseMessageFileOptions>): Promise<ChooseMessageFileResult | false> 聊天选文件;count 钳制 1–9;失败 resolve(false)
chooseMedia (params?: Partial<ChooseMediaOptions>): Promise<ChooseMediaResult | false> 选媒体;count 钳制 1–9、默认 mediaType:['image','video'];失败 resolve(false)
scanCode (params?: ScanCodeOptions): Promise<ScanCodeResult | false> 扫码;scanType 默认 ['qrCode','barCode'](二维码+一维码);经 getUni() 调用,失败(含取消)resolve(false)
previewMedia (params?: Partial<PreviewMediaParams>): void 图片/视频预览;按 URL 后缀自动推断 type,无效资源过滤
downloadFile (params: DownloadFileParams): Promise<string | false> 下载;url 经 urlConversion 转 https;fileName 自动拼 USER_DATA_PATH;失败 resolve(false)
openDocument (params: OpenDocumentParams): Promise<boolean> 打开文档;filePath 必填;失败 resolve(false)
filePreviewShare (fileName?, downloadParams?, openParams?): void 组合封装:下载 → 打开文档
saveImageToPhotosAlbum (filePath?, options?: SaveImageOptions): void 存图到相册;options.mode:'direct'(默认)/'authorize';权限拒绝引导去设置
chooseLocation (params?: ChooseLocationOptions): Promise<ChooseLocationResult | false> 打开地图选位置;mode 同上(默认 'direct');checkSystem(默认 true)预检系统定位开关;失败 resolve(false)
getLocation (params?: GetLocationOptions): Promise<GetLocationResult | false> 获取当前坐标;与 chooseLocation 同构的 scope.userLocation 授权 + mode + checkSystem,无 UI;失败 resolve(false)
updateApplet (): void 检查小程序更新(getUpdateManager 封装)
addPhoneContact (params?: AddPhoneContactParams): Promise<boolean> 存联系人;getSetting 权限检查 + authorize/引导设置;字段对齐官方命名;成功 resolve(true) / 失败 resolve(false)
getLoginCode (params?: GetLoginCodeParams): Promise<string | false> 登录 code;provider 缺省时经 getProvider({service:'oauth'}) 动态获取(优先 weixin);失败 resolve(false)
getScreenBrightness (params?: GetScreenBrightnessParams): Promise<number | false> 屏幕亮度;成功返回 0~1 数值,失败 resolve(false)
getDomInfo (params: GetDomInfoParams): Promise<SelectorQueryNodeInfo[]> 节点布局信息;selector/component 为空时 reject(new Error(...)),需 try/catch
getImageInfo (params?: GetImageInfoParams): Promise<GetImageInfoResult | false> 图片信息;src 经 urlConversion;src 空或失败 resolve(false)
getSystemInfoSync (): GetSystemInfoSyncResult 同步;合并官方 5 个 getter(替代废弃 getSystemInfoSync)
rpxToPx (rpx: number): number rpx → px;公式 rpx * screenWidth / 750;screenWidth 经 getSystemInfoSync() 读取并 Number() 兜底 750;非 uni 环境由 getUni() 抛错
pxToRpx (px: number): number px → rpx;公式 px * 750 / screenWidth;screenWidth 同样 Number() 兜底 750;非 uni 环境由 getUni() 抛错
backRefresh (options?: Partial<BackRefreshOptions>): void 返回上一页并调用其 $vm 方法(默认 refreshPage,携带 data);设置 path 时经 switchTab/redirectTo 跳转目标页(data 经 queryString 序列化);无上一页兜底首页;delta≥1、duration≥0,延迟执行规避页面栈未就绪
storageWatcher class StorageWatcher + export const storageWatcher: StorageWatcher(全局唯一单例) 可监听本地缓存事件中心(class 封装);基于 uni 缓存 API,支持指定 key 与全局 "*" 监听、变更早于监听注册时的暂存事件自动补发;setStorageWatch/setStorageWatchAsync/removeStorageWatch/clearStorageWatch 触发变更;watchStorage 返回取消函数
import {
  showToast,
  chooseMedia,
  scanCode,
  getLoginCode,
  getSystemInfoSync,
  rpxToPx,
  pxToRpx,
  backRefresh,
  storageWatcher, // 可监听本地缓存事件中心(全局唯一单例,推荐直接使用)
} from "@xiaojinquan/super-kit/utils";

showToast("保存成功");

const media = await chooseMedia({ count: 1, mediaType: ["image"] });
if (media) console.log(media.tempFiles);

const scanned = await scanCode(); // 默认 scanType: ['qrCode','barCode']
if (scanned) console.log(scanned.result, scanned.scanType);

const code = await getLoginCode();
if (code) console.log(code);

const sys = getSystemInfoSync(); // 同步返回

const px = rpxToPx(100);  // 设备屏宽 375 时返回 50
const rpx = pxToRpx(50);  // 返回 100

失败处理约定:多数 choose / 文件类方法(chooseMessageFile chooseMedia scanCode chooseLocation getLocation downloadFile openDocument getScreenBrightness getImageInfo getLoginCode addPhoneContact)失败 resolve(false)、不 reject,调用方 if (res) 判空即可;getDomInfo 对入参错误 reject,需 try/catch;getSystemInfoSync 为同步函数。部分能力为微信小程序 / App 专属(如 saveImageToPhotosAlbum 相册权限、addPhoneContact 通讯录权限、5 个 getter),H5 / 各端支持度不同,宜按平台条件调用(如 #ifdef MP-WEIXIN)。

4.16.1 storageWatcher — 可监听本地缓存事件中心(全局唯一单例)

对 uni 本地缓存(getStorageSync / setStorageSync / setStorage / removeStorageSync / getStorageInfoSync / clearStorageSync)做可监听封装。**已封装为 class StorageWatcher,并导出全局唯

Related Packages

@composy/icons-vue2

icons Vue 2 icon component package

0
@iss-ai/vue-canvas-core

Core utilities and engine for vue-canvas

4,028
stellar-ui-v2

StellarUI组件库,支持全量引入和按需引入

7,002 3
dify-chat-bot

Dify机器人工具包

0

Version History

Version Released Vue License
0.0.20 ^2.7.0 || >=3.0.0 Proprietary
0.0.19 ^2.7.0 || >=3.0.0 Proprietary
0.0.18 ^2.7.0 || >=3.0.0 Proprietary
0.0.17 ^2.7.0 || >=3.0.0 Proprietary
0.0.16 ^2.7.0 || >=3.0.0 Proprietary