# x-tools 工具库使用文档 x-tools 是基于 uni-app 打造的通用工具集合,覆盖通用工具函数、界面语法糖、路由导航、H5 与小程序专用能力等常见场景。所有模块均可单独按需引入,也可以通过主入口统一管理,帮助你在跨端项目中快速复用能力。 ## 支持平台 - 微信小程序 - 支付宝小程序 - App(uni-app 运行时) - H5 / Web > 具体 API 是否可用需参考 uni-app 官方文档及平台限制,文档中带有 `#ifdef` 注释的能力仅在对应平台有效。 ## 快速开始 1. 确保工程已经安装并同步 `uni_modules/x-tools` 模块。 2. 在需要的页面或模块中引入工具函数: ```javascript import { promisify, countDown } from "@/uni_modules/x-tools/tools/index.js" import { toast } from "@/uni_modules/x-tools/tools/sugar.js" ``` 3. 对于 Vue2 项目,请在入口文件执行 `promisify()` 以启用 Promise 化支持。 ## 模块总览 | 模块 | 文件路径 | 主要能力 | | --- | --- | --- | | 通用工具 | `tools/index.js` | Promise 包装、类型判断、页面信息、倒计时、轮询、深拷贝等 | | 语法糖 | `tools/sugar.js` | 日志、提示、剪贴板、地图、客服、图片保存、表单校验等 | | 路由导航 | `tools/router.js` | 路由跳转、事件通道数据透传、延时跳转 | | H5 专用 | `tools/h5Utils.js` | 调试面板、URL 参数、公众号与生活号授权及支付 | | 小程序专用 | `tools/appletUtils.js` | 视频号直跳、微信分享参数、场景值解析 | | 异步重试 | `tools/retryAsync.js` | 支持退避策略的 Promise 重试工具 | | 码工具 | `tools/codeUtil.js` | 扫码、编码与解码工具类 | | 组件辅助 | `tools/com.js` | 通用组件属性定义、尺寸转换 | ## 通用工具(`tools/index.js`) 主入口导出了常用函数,并将其他工具模块聚合到命名空间中: ```javascript import * as tools from "@/uni_modules/x-tools/tools/index.js" const { sugar, router, h5Utils, appletUtils } = tools ``` ### 基础能力 - `promisify()`:在 Vue2 项目中调用后,可让内置 `uni` API 返回 Promise,便于 `async/await` 调用。 - `isPromise(obj)`:判断目标是否符合 Promise 接口,常用于链式调用的防御性编程。 - `_typeof(value)`:返回更精确的类型字符串(如 `array`、`date`、`set`)。 - `sleep(ms)`:返回在指定毫秒后 resolve 的 Promise,用于节流、动画等待等场景。 - `deepClone(target, map?)`:支持 Map、Set、Symbol 等复杂结构的深拷贝工具,自动处理循环引用。 ### 页面辅助 - `getCurrentPage()`:获取当前页面实例,等价于 `getCurrentPages().slice(-1)[0]`。 - `getCurrentPagePath(fullPath = false)`:返回当前页面路径,可选包含 query。 - `isTabBarPage(path?)`:判断当前页面或指定路径是否在 `pages.json` 的 tabBar 配置中。 - `getPageInfo()`:返回 `{ currentPage, startPage, isSharePage, pageStackLen }`,用于埋点与分享判断。 ### 计时与轮询 - `countDown(endTime, callback, formatStr = "hh:mm:ss", refreshRate = 100)`:基于毫秒级刷新倒计时,`callback(info, isEnd)` 中的 `info` 带有格式化文本及 `d/h/m/s` 数据。 - `pollingForResult(fun, params, judgeFun, ms = 1000, timeout = 60000)`:轮询异步函数直到 `judgeFun` 返回 `success` 或 `fail`。 - `pollingForData(fun, params, callback, ms = 1000)`:持续轮询并在每次调用后触发回调,返回的函数可立即停止轮询。 ```javascript const timer = countDown("2025-12-31 23:59:59", ({ str }) => { this.countDownText = str }) const task = () => api.getResult() await pollingForResult(task, [], res => res.status === "OK" ? "success" : undefined) ``` ### 模块聚合 `index.js` 将其他工具按命名空间导出,可通过 `router.navTo`、`sugar.toast` 等方式直接使用,便于统一管理依赖。 ## 语法糖模块(`tools/sugar.js`) ### UI 与交互 - `toast(title, options?)`:封装 `uni.showToast`,默认 2 秒无图标,支持自定义 `icon` 与 `duration`。 - `previewImage(urls, current, options?)`:图片预览,自动接管失败回调。 - `saveImage(url, tips = true)`:支持 H5 下载和小程序或 APP 保存到相册,可选是否提示。 - `log(...args)`:`console.log` 简写。 ### 系统能力 - `makePhoneCall(phoneNumber)`:拨打电话并输出失败日志。 - `openMap(lng, lat, name, address, options?)`:打开地图定位。 - `toCustomerService(corpId, url)`:跳转企业微信客服,支持微信小程序、APP、H5。 - `pageEvent.call(this)`:Vue2 页面获取事件通道,需绑定页面实例。 ### 数据与表单 - `isEmpty(value)` 与 `hasEmptyField(obj, excludedKeys = [])`:识别空值与未填写字段,返回首个空字段路径。 - `setStorage(key, value)`:同步缓存。 - `object2queryStr(obj)`:对象转查询字符串,自动补齐 ? 与 &。 - `html2text(html)`:去除标签和实体。 - `dataMask(str, head, tail)`:按位数脱敏,可用于手机号或证件号。 ### 其他辅助 - `upx2px(val)`:将 upx 或 rpx 转换成像素。 - `copy(str, options?)`:复制内容到剪贴板。 - `queryElementRect.call(this, selector)`:基于 `uni.createSelectorQuery` 获取元素布局信息,支持数组批量查询。 ```javascript import { toast, dataMask, hasEmptyField } from "@/uni_modules/x-tools/tools/sugar.js" if (hasEmptyField(formData)) { toast("请完善表单信息") } const phone = dataMask("13800138000", 3, 4) ``` ## 路由模块(`tools/router.js`) - `navTo(url, options?, timeout = 0)`:普通页面跳转,可设置延时与额外参数。 - `redTo(url, timeout)`:`uni.redirectTo` 封装。 - `clearTo(url, timeout)`:`uni.reLaunch` 封装,清空页面栈。 - `tabTo(url, timeout)` 与 `shTab(url, timeout)`:跳转到 tabBar 页面。 - `navBack(timeout = 0, delta = 1)`:返回上一页。 - `navToAndEvent(url, data, acceptCallback?, timeout)`:跳转并通过事件通道传递数据,返回 Promise 获取回传值。 - `navBackAndEvent(eventChannel, backData, timeout, delta)`:在返回前向来源页面发送 `backData`。 ```javascript import { navToAndEvent, navBackAndEvent } from "@/uni_modules/x-tools/tools/router.js" await navToAndEvent("/pages/detail/detail", { id: 1 }, res => { console.log("detail 返回数据", res) }) const eventChannel = this.getOpenerEventChannel() eventChannel.on("navData", data => { this.detailId = data.id }) navBackAndEvent(eventChannel, { updated: true }) ``` ## H5 专用工具(`tools/h5Utils.js`) - `debug(tip = true)`:动态加载 eruda 调试面板,失败时自动尝试多组 CDN。 - `getQueryParams(url?)`:解析 URL 查询字符串,默认读取当前地址。 - `judgeBrowser()`:识别浏览器环境,返回 `wx`、`ali` 或 `unknown`。 - `loadScript(src)`:动态注入 script,返回加载完成的节点。 - `getWxAuthCode(appId, state?, scope?)`:发起微信公众号 OAuth 授权,scope 默认为 `snsapi_base`。 - `wxConfig(params)`:基于签名参数配置 `jWeixin`,内部包含常用 API 列表。 - `wxPay(params)`:调用 `chooseWXPay` 发起公众号支付。 - `wxShare(params)`:设置好友与朋友圈分享信息。 - `getAliAuthCode(appId, scope?)`:支付宝生活号授权,支持 `auth_base` 与 `auth_user`。 - `aliPay(tradeNO)`:支付宝生活号支付封装。 ```javascript import { debug, getQueryParams, wxPay } from "@/uni_modules/x-tools/tools/h5Utils.js" debug() const { orderNo } = getQueryParams() await wxPay(payParams) ``` ## 小程序工具(`tools/appletUtils.js`) - `toChannelsLive(finderUserName)`:在微信小程序内跳转视频号直播,自动提示错误信息。 - `getWxShareParams(queryParams?, title?, imageUrl?, path?)`:生成小程序分享配置,默认读取当前页面参数并补充标题与路径。 - `getSceneParams()`:解析小程序场景值(如扫码进入),内部复用 `h5Utils.getQueryParams` 处理 `scene`。 ```javascript import { getWxShareParams } from "@/uni_modules/x-tools/tools/appletUtils.js" onShareAppMessage() { return getWxShareParams({ source: "invite" }, "邀请你加入", "/pages/index/index") } ``` ## 异步重试工具(`tools/retryAsync.js`) `retryAsync(asyncFn, options)` 为任意 Promise 操作提供自动重试,支持自定义退避策略、超时控制与钩子。 | 选项 | 默认值 | 说明 | | --- | --- | --- | | `maxRetries` | `3` | 最大允许的重试次数(不含首次执行)。 | | `delay` | `1000` | 首次重试前的等待时间,单位毫秒。 | | `backoffStrategy` | `fixed` | 退避策略:`fixed`、`exponential`、`linear`。 | | `backoffFactor` | `2` | 指数退避或线性退避时的增长因子。 | | `shouldRetry(error, attempt)` | `() => true` | 返回 `false` 可终止后续重试。 | | `onRetry(error, attempt, max)` | `() => {}` | 每次准备重试时触发,可用于埋点。 | | `timeout` | 空 | 单次任务超时时间,超时会抛出异常并进入重试流程。 | ```javascript import { retryAsync } from "@/uni_modules/x-tools/tools/retryAsync.js" const fetchWithRetry = () => retryAsync(() => api.fetchData(), { maxRetries: 5, backoffStrategy: "exponential", shouldRetry: (err, attempt) => err.code !== "INVALID_TOKEN", onRetry: (err, attempt) => console.log(`retry ${attempt}`, err.message) }) ``` ## 码工具(`tools/codeUtil.js`) - `new CodeUtil(codeTypeArray)`:实例化时声明支持的码类型(数组顺序即类型索引)。 - `codeUtil.scan(options?)`:调用 `uni.scanCode` 扫码。 - `codeUtil.getCodeInfo(options?)`:扫码并解析内置编码格式,返回 `{ type, content }`。 - `codeUtil.makeCode(type, content)`:生成带类型索引的 JSON 字符串,便于反向解析。 - `codeUtil.parseCode(codeInfo)`:解析任意字符串,返回码类型或错误信息。 ```javascript import { CodeUtil } from "@/uni_modules/x-tools/tools/codeUtil.js" const codeUtil = new CodeUtil(["user", "product"]) const payload = codeUtil.makeCode("user", { id: 123 }) const info = codeUtil.parseCode(payload) ``` ## 组件辅助(`tools/com.js`) - `commonProps`:通用组件属性集合,包含 `bgColor`、`customStyle` 等常用配置,便于在多个组件复用。 - `str2px(str)`:将 `750rpx`、`100px`、`50` 等字符串转换成像素值,与 `sugar.upx2px` 配合使用可统一渲染尺寸。 ```javascript import { commonProps, str2px } from "@/uni_modules/x-tools/tools/com.js" export default { props: { ...commonProps, width: { type: String, default: "750rpx" } }, computed: { pixelWidth() { return str2px(this.width) } } } ``` ## 组合示例 ```javascript import { countDown, pollingForData } from "@/uni_modules/x-tools/tools/index.js" import { toast, hasEmptyField } from "@/uni_modules/x-tools/tools/sugar.js" import { navTo } from "@/uni_modules/x-tools/tools/router.js" export default { data() { return { countdownText: "", form: { phone: "", code: "" } } }, onLoad() { this.timerId = countDown(Date.now() + 5 * 60 * 1000, ({ str }, finished) => { this.countdownText = str if (finished) toast("倒计时结束") }) this.stopPolling = pollingForData(() => api.checkStatus(), [], (err, res) => { if (res?.done) { this.stopPolling() navTo("/pages/result/result?id=" + res.id) } }, 2000) }, methods: { submit() { if (hasEmptyField(this.form)) return toast("请填写完整") } }, onUnload() { clearInterval(this.timerId) this.stopPolling && this.stopPolling() } } ``` ## 注意事项 - **平台差异**:带有 `#ifdef` 宏的函数仅在对应平台可用,调用前请先判断运行环境。 - **权限与授权**:保存图片、拨打电话、支付等能力需提前申请相应权限或签名。 - **网络依赖**:文件下载、远程支付等需要网络通畅并在 HTTPS 环境下运行。 - **错误处理**:工具内部会在失败时打印日志,建议在业务代码中补充 `try/catch` 或失败提示。 - **性能考量**:轮询与倒计时应适度释放资源,在页面卸载时清理定时器与停止函数。 ## 更多信息 - 最新功能与修复请查看 `changelog.md`。 - 如需扩展工具模块,推荐在 `tools` 目录下新增文件并通过 `index.js` 统一导出。