@pit-frontend-framework/utils
v1.0.2
Published
湖南创智艾泰克科技有限公司-前端组工具库
Readme
@pit-frontend-framework/utils
湖南创智艾泰克科技有限公司 — 前端工具库
为 Vue 3 + Vite 企业级项目提供开箱即用的工具函数、钩子与上下文注入能力。
pnpm add @pit-frontend-framework/utils目录
| 模块 | 说明 |
| :--- | :--- |
| 应用配置 appConfig | 初始化与读取运行时配置 |
| 运行时常量 define | 从 AppConfig 派生的响应式常量 |
| 认证存储 auth | Token / Lock / PasswordLock 的 localStorage 读写 |
| 请求客户端 request | 基于 axios 的可配置 HTTP 客户端 |
| 权限上下文 permissionContext | 动态注入权限数据,提供 hasP / hasBtnP / hasFormP |
| 路由上下文 routerContext | 注入当前路由解析函数 |
| 日期工具 date | 多格式日期格式化、时间差计算 |
| 对象工具 object | 深拷贝、深合并、URL 参数序列化等 |
| 树形工具 tree | 树遍历、树扁平化、数组转树 |
| 表单验证 form | 预置正则验证器、列过滤工具 |
| 密码校验 password | 企业级密码复杂度校验 |
| 存储适配器 storage | 带前缀的 localStorage 适配器 |
| 浏览器工具 browser | DOM 操作、文件下载、文件大小格式化 |
| 剪贴板 clipboard | 跨浏览器文本复制 |
| 打印 print | 区域打印、内容生成 |
| 事件总线 emitter | 基于 mitt 的全局事件总线 |
| 跨标签广播 broadcastService | 基于 BroadcastChannel 的多标签通信 |
| 国际化 i18n | 注入 vue-i18n 实例,内置中英文语言包 |
| JWKS 加密 jwks | RSA 公钥加密(JWKS 协议) |
| 本地缓存工具 localCache | URL 参数 / localStorage 快捷读取 |
| 滚动工具 scroll | 缓动平滑滚动 |
| 表格列宽 tableSize | 响应不同表格密度的列宽常量 |
| 通用校验 validate | URL、邮件、经纬度等格式校验 |
| 页面工具 page | 页面标题构建 |
| 组件安装 install | Vue 组件 install 辅助函数 |
| pit 业务集合 pit | 权限 / 流程 / 数字 / 日期等业务常用操作的聚合对象 |
| 全局常量 constants | IS_OK、BIDTYPE 等通用业务常量 |
一、应用配置 appConfig
框架要求在
main.ts中createApp()之前 调用初始化函数,其他模块的运行时常量依赖此配置。
AppConfig 接口
| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| mode | string | 运行模式,如 'development' / 'production' |
| baseUrl | string | 请求前缀(axios baseURL) |
| timeout | number | 请求超时(ms) |
| baseApi | string | 后台 API 地址前缀 |
| loginTitle | string | 登录页面标题 |
| loginAuthor | string | 登录页面著作 |
| title | string | 网站标题 |
| jm | string | 积木地址 |
| sort | string | 排序服务地址 |
| wssUrl | string | WebSocket URL |
| bimApi | string | BIMWin URL |
| enablePageOffice | boolean | 是否启用 PageOffice |
| jwksKid | string? | JWKS 公钥 kid |
initAppConfigFromViteEnv(env, overrides?)
从 Vite 的 import.meta.env 初始化配置,自动完成 env var → AppConfig 字段的映射。
| 参数 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| env | Record<string, string \| boolean \| undefined> | 是 | import.meta.env |
| overrides | Partial<AppConfig> | 否 | 覆盖任意字段 |
// main.ts
import { initAppConfigFromViteEnv } from '@pit-frontend-framework/utils';
initAppConfigFromViteEnv(import.meta.env);
// 或覆盖超时
initAppConfigFromViteEnv(import.meta.env, { timeout: 30000 });约定的 env var 映射:
| env var | AppConfig 字段 |
| :--- | :--- |
| VITE_APP_DEFINE_BASE_URL | baseUrl |
| VITE_APP_BASE_API | baseApi |
| VITE_APP_DEFINE_LOGIN_TITLE | loginTitle |
| VITE_APP_DEFINE_LOGIN_AUTHOR | loginAuthor |
| VITE_APP_TITLE | title |
| VITE_APP_JM | jm |
| VITE_APP_SORT | sort |
| VITE_APP_BASE_WSS | wssUrl |
| VITE_APP_BIM_API | bimApi |
| VITE_APP_ENABLE_PAGEOFFICE | enablePageOffice |
initAppConfig(config)
手动传入完整配置对象进行初始化(适用于非 Vite 环境)。
getAppConfig()
获取只读配置对象,未初始化时抛出错误。
import { getAppConfig } from '@pit-frontend-framework/utils';
const { baseUrl, title } = getAppConfig();onAppConfigReady(cb)
注册回调,在配置初始化完成时执行;若已初始化则立即执行。适用于依赖配置的模块延迟初始化。
二、运行时常量 define
由 AppConfig 在初始化时自动填充的 ESM live binding 常量,无需手动赋值。
import {
DEFINE_MODE, DEFINE_BASE_URL, DEFINE_TITLE,
DEFINE_LOGIN_TITLE, DEFINE_LOGIN_AUTHOR,
WSS_URL, BIM_API, ENABLE_PAGEOFFICE,
DEFINE_JWKS_KID, DEFINE_JWKS_PATH,
DEFINE_JM, DEFINE_SORT, DEFINE_TIME,
} from '@pit-frontend-framework/utils';原理:利用 ESM live bindings,
initAppConfig()调用后所有导入方自动获取最新值,无需重新导入。
三、认证存储 auth
对 localStorage 的 Token / Lock / PasswordLock 三类 key 进行统一管理,key 名称可自定义。
Token 操作
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| getToken | () => string \| null | 读取 token |
| setToken | (token: string) => void | 写入 token |
| removeToken | () => void | 删除 token |
Lock 操作
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| getLock<T> | () => T \| null | 读取锁屏数据(自动 JSON 反序列化) |
| setLock | (value: unknown) => void | 写入锁屏数据 |
| removeLock | () => void | 删除锁屏数据 |
PasswordLock 操作
与 Lock 操作对称,函数名为 getPasswordLock / setPasswordLock / removePasswordLock。
自定义键名
import { setAuthStorageKeys, resetAuthStorageKeys } from '@pit-frontend-framework/utils';
setAuthStorageKeys({ token: 'my_token', lock: 'my_lock' });
// 恢复默认
resetAuthStorageKeys();四、请求客户端 request
RequestHooks 接口
| 钩子 | 类型 | 说明 |
| :--- | :--- | :--- |
| onRequest | (config) => config | 请求前拦截(适合注入 token) |
| onRequestError | (error) => unknown | 请求异常处理 |
| onResponse | (response) => unknown | 响应成功处理(适合解包 data) |
| onResponseError | (error) => unknown | 响应异常处理 |
createRequestClient(options?)
创建独立的 axios 实例,携带默认请求头与序列化配置。
| 参数 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| options.axiosConfig | CreateAxiosDefaults | 否 | 透传给 axios.create() |
| options.hooks | RequestHooks | 否 | 局部生命周期钩子 |
- 返回值:
AxiosInstance
// src/utils/request.ts
import { setRequestHooks } from '@pit-frontend-framework/utils';
setRequestHooks({
onRequest: (config) => {
const token = localStorage.getItem('token');
if (token) config.headers.set('Authorization', `Bearer ${token}`);
return config;
},
onResponse: (response) => response.data,
onResponseError: (error) => {
console.error(error);
return Promise.reject(error);
},
});setRequestHooks(hooks?) / getRequestHooks() / resetRequestHooks()
配置全局默认拦截钩子。
优先级:局部 hooks > setRequestHooks 全局 hooks > window 回调(兼容兜底)。
request(默认实例)
开箱即用的 axios 实例,baseURL 和 timeout 在 AppConfig 初始化后自动更新。
http
import { http } from '@pit-frontend-framework/utils';
const data = await http.request<UserInfo>({ url: '/api/user', method: 'GET' });五、权限上下文 permissionContext
框架包不直接依赖宿主的 store,由宿主在启动时注入权限数据的解析函数。
setPermissionContext(ctx)
在 main.ts 中注入权限上下文:
import { setPermissionContext } from '@pit-frontend-framework/utils';
import { useUserStore } from '@/store';
setPermissionContext({
getPermissionList: () => useUserStore().permissionList,
getModelId: () => String(router.currentRoute.value.meta.modelId ?? ''),
});PermissionContext 接口
| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| getPermissionList | () => PermissionItem[] | 返回当前用户的权限列表 |
| getModelId | () => string | 返回当前页面的 modelId |
| getSnapshot | () => PermissionSnapshot | 返回权限快照(备用方式) |
| storage | Storage | 自定义 storage(默认 localStorage) |
| storageKeys | { administrator?, projectManager? } | 自定义存储键名 |
权限判断函数
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| hasP | (enCode: string) => boolean | 判断是否有指定列权限 |
| hasBtnP | (enCode: string) => boolean | 判断是否有指定按钮权限 |
| hasFormP | (enCode: string) => boolean | 判断是否有指定表单权限 |
| adminAuthority | () => boolean | 是否为管理员 |
| isProjectManager | () => boolean | 是否为项目经理 |
import { hasBtnP } from '@pit-frontend-framework/utils';
if (hasBtnP('btn_add')) {
// 显示新增按钮
}六、路由上下文 routerContext
框架包不直接依赖宿主路由,由宿主注入当前路由解析函数。
setRouteResolver(fn)
// main.ts
import { setRouteResolver } from '@pit-frontend-framework/utils';
import router from '@/router';
setRouteResolver(() => router.currentRoute.value);getCurrentRoute()
返回 { params, query, meta } 的当前路由对象;未注入时返回空对象(安全降级)。
getRouter(type, queryType?)
从当前路由的 params / query / meta 中按 key 取值:
import { getRouter } from '@pit-frontend-framework/utils';
const projectId = getRouter('projectId'); // 自动从 params/query/meta 查找
const userId = getRouter('userId', 'query'); // 仅从 query 取七、日期工具 date
toDate(v, format?)
将日期值格式化为字符串,支持秒级时间戳、毫秒级时间戳、/Date(timestamp)/ 格式、ISO 字符串。
| 参数 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| v | Date \| string \| number \| null \| undefined | — | 日期值 |
| format | string | 'yyyy-MM-dd HH:mm' | 格式模板(yyyy/MM/dd/HH/mm/ss) |
- 返回值:
string,输入无效时返回''
import { toDate } from '@pit-frontend-framework/utils';
toDate(new Date(), 'yyyy-MM-dd'); // '2026-04-29'
toDate(1714348800, 'yyyy/MM/dd HH:mm:ss'); // 时间戳(秒)
toDate('2026-04-29T10:00:00'); // '2026-04-29 10:00'dateFormat(date, fmt?)
基于 dayjs 的格式化,支持 YYYY/MM/DD/HH/mm/ss 等 dayjs token。
- 返回值:
string
handleDateStr(dateStr)
将 yyyy-MM-dd 转换为 yyyy年MM月dd日 中文格式。
- 返回值:
string
dateDiff(startDate, endDate)
计算两个日期字符串(yyyy-MM-dd)之间的天数差。
- 返回值:
number
八、对象工具 object
deepClone<T>(source)
深拷贝,支持嵌套对象和数组。
import { deepClone } from '@pit-frontend-framework/utils';
const copy = deepClone({ a: { b: 1 } });objectMerge<T>(target, source)
深合并两个对象,source 中已存在的键不会覆盖 target 中的同名键(保留 target 优先)。
cleanArray(arr)
过滤数组中的所有假值(含 0、''、null、undefined)。
param(obj)
对象序列化为 URL 查询字符串(忽略值为 undefined 的键)。
param({ a: 1, b: undefined, c: '中文' }); // 'a=1&c=%E4%B8%AD%E6%96%87'param2Obj(url)
解析 URL 的查询字符串为对象。
appendObjectToPath(path, obj)
将对象参数追加到路径后:/api/list?a=1&b=2。
formatFloat(val, decimals?, max?, min?, negative?)
数字格式化,限制小数位数和取值范围。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| val | string \| number | 输入值 |
| decimals | 2 \| 3 \| 4 | 小数位数,不传则只允许整数 |
| max | number | 最大值 |
| min | number | 最小值 |
| negative | boolean | 是否允许负数 |
amountThousandsConversion(amount, decimals?)
金额千分位格式化,如 1234567.89 → '1,234,567.89'。
uniqueArr<T>(arr)
数组去重。
createUniqueString()
生成唯一字符串(Date.now().toString(36) + 随机后缀)。
byteLength(str)
计算字符串字节长度(中文按 3 字节计算)。
九、树形工具 tree
TreeNode 接口
interface TreeNode {
children?: TreeNode[] | null;
hasChildren?: boolean;
id?: string | number;
parentId?: string | number;
[key: string]: unknown;
}iterationArr(nodes, cb, childrenKey?)
递归遍历节点数组及其所有子节点。
import { iterationArr } from '@pit-frontend-framework/utils';
iterationArr(treeData, (node) => {
node.disabled = true;
});iterationArrEnd(nodes, cb, childrenKey?)
同上,但回调返回 false 时提前终止遍历。
treeToArray<T>(list)
树形结构扁平化为数组(深拷贝,不修改原数据,子节点 children 置为 null)。
import { treeToArray } from '@pit-frontend-framework/utils';
const flat = treeToArray(treeData);arrayToTree(items, config?)
扁平数组按 parentId 构建标准树结构(children 字段)。
toTreeViewJson(items)
扁平数组转为 TreeView JSON(ChildNodes 字段,根节点 parentId 为 0 或 '0')。
十、表单验证 form
formValidate(type, msg?)
创建 Element Plus el-form-item 规则使用的验证函数。
| 参数 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| type | FormValidateType \| string | 是 | 预置类型名称 或 自定义正则字符串如 '/^foo$/' |
| msg | string | 否 | 自定义错误消息 |
- 返回值:
(rule, value, callback) => void
预置类型(FormValidateType):
| key | 含义 |
| :--- | :--- |
| iphone | 手机号 |
| password | 6-16 位数字+字母混合密码 |
| idCard | 身份证号 |
| email | 邮箱 |
| plateNumber | 车牌号 |
| chinese | 纯中文 |
| enCode | 字母/数字开头结尾,中间可含小数点 |
| userAccount | 纯数字英文 |
| english | 纯英文 |
| fullName | 不含特殊符号 |
| bigInt | 正整数 |
| netUrl | http/ftp/file URL |
import { formValidate } from '@pit-frontend-framework/utils';
const rules = {
phone: [{ validator: formValidate('iphone') }],
custom: [{ validator: formValidate('/^[A-Z]{3}$/', '必须是三位大写字母') }],
};handleRules(simpleRules, extraRules?)
批量构建简写表单规则:字符串值自动转为 { required: true, message, trigger: ['input'] }。
import { handleRules } from '@pit-frontend-framework/utils';
const rules = handleRules({ name: '请输入名称', code: '请输入编码' });filterColumns(columns, hasFlow, insertIndex?, approvalColumn?)
根据流程状态决定是否插入审批状态列(prop: 'approvalStatus')。
toggleColumnByProp(columns, show, prop, column?, insertIndex?)
通用列切换:按 prop 动态插入或移除指定列。
十一、密码校验 password
passwordValidate(pwd)
验证密码是否满足企业级复杂度要求:
12-16 位
包含数字、大写字母、小写字母、特殊字符四类
不能有连续 4 位相同字符
不能有连续 4 位字母/数字/键盘横向/斜向序列
返回值:
boolean
checkPasswordComplexity(pwd)
返回详细校验结果 { valid, message },消息支持 i18n。
import { checkPasswordComplexity } from '@pit-frontend-framework/utils';
const { valid, message } = checkPasswordComplexity('Abc123!@#xyz');
if (!valid) ElMessage.error(message);十二、存储适配器 storage
createStorage(options?)
创建带前缀的存储适配器,值自动 JSON 序列化/反序列化。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| options.prefix | string | key 前缀,默认 '' |
| options.storage | Storage | 底层存储,默认 localStorage(SSR 自动降级为内存存储) |
- 返回值:
StorageAdapter
import { createStorage } from '@pit-frontend-framework/utils';
const store = createStorage({ prefix: 'app_' });
store.set({ theme: 'dark', lang: 'zh' });
store.get<string>('theme'); // 'dark'
store.remove('theme');
store.clear(); // 仅清除 app_ 前缀的 key全局快捷函数
import { storageGet, storageSet, storageRemove, storageClear } from '@pit-frontend-framework/utils';
storageSet({ userId: '123' });
storageGet('userId'); // '123'十三、浏览器工具 browser
DOM 操作
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| hasClass | (el, cls) => boolean | 判断是否有 class |
| addClass | (el, cls) => void | 添加 class |
| removeClass | (el, cls) => void | 移除 class |
| toggleClass | (el, cls) => void | 切换 class |
| html2Text | (html) => string | 提取 HTML 纯文本 |
文件操作
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| fileType | (ext) => string | 后缀 → 文件类型分类(image/document/video/audio/archive/other) |
| formatFileSize | (size) => string | 字节数 → '1.23 MB' |
| downloadTemplate | (blob, fileName) => void | Blob 下载 |
| downloadTemplateAddType | (res, fallbackName) => void | 从响应头提取文件名并下载 Blob |
| downloadUrlFile | (url, fileName) => Promise<void> | 从 URL 下载文件 |
import { formatFileSize } from '@pit-frontend-framework/utils';
formatFileSize(1048576); // '1.00 MB'路由跳转
| 函数 | 说明 |
| :--- | :--- |
| goToRouteWithThePlatform(url, target, cb?, timer?) | 系统内部 hash 路由跳转(延迟 1s) |
| goToRouteOutThePlatform(url, target, cb?, timer?) | 外部链接跳转 |
十四、剪贴板 clipboard
copyClipboard(text, options?)
复制文本到剪贴板。优先使用 navigator.clipboard,降级到 execCommand('copy')。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| text | string | 要复制的文本 |
| options.onError | (error) => void | 复制失败回调 |
- 返回值:
Promise<boolean>
import { copyClipboard, setClipboardFeedbackHandler } from '@pit-frontend-framework/utils';
import { ElMessage } from 'pit-element-plus';
// 全局配置复制反馈(一次性设置)
setClipboardFeedbackHandler(({ message, type }) => ElMessage({ message, type }));
await copyClipboard('Hello World');十五、打印 print
Print(target, options?)
在隐藏 iframe 中执行区域打印,自动注入当前页面样式。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| target | string \| HTMLElement \| { $el: HTMLElement } | 选择器、DOM 元素或 Vue 组件实例 |
| options.noPrint | string | 不打印的元素选择器,默认 '.no-print' |
import { Print } from '@pit-frontend-framework/utils';
Print('#print-area');
Print(tableRef.value.$el, { noPrint: '.no-print,.action-bar' });createPrintContent(target, options?)
仅生成打印 HTML 字符串(含样式快照),不触发打印。适用于自定义打印逻辑。
- 返回值:
string
MyPrint(target, options?)
Print() 的别名(旧版兼容)。
十六、事件总线 emitter
基于 mitt,提供类型安全的全局事件总线。
import { emitter, createEmitter } from '@pit-frontend-framework/utils';
// 使用全局单例
emitter.on('refresh', () => { /* 刷新列表 */ });
emitter.emit('refresh');
emitter.off('refresh', handler);
// 创建独立实例
const myEmitter = createEmitter();十七、跨标签广播 broadcastService
基于 BroadcastChannel API,实现同域多个浏览器标签之间的双向通信。
getBroadcastService()
获取默认的广播服务实例(频道名:'app-channel')。
BroadcastService 方法
| 方法 | 签名 | 说明 |
| :--- | :--- | :--- |
| on<T> | (eventType, handler) => () => void | 注册监听,返回取消函数 |
| once<T> | (eventType, handler) => void | 注册一次性监听 |
| off | (eventType, handler) => void | 移除监听 |
| postMessage<T> | (eventType, data?, triggerSelf?) => void | 广播事件(默认同时触发自身) |
| close | () => void | 关闭频道,释放资源 |
import { getBroadcastService } from '@pit-frontend-framework/utils';
import { onUnmounted } from 'vue';
const broadcast = getBroadcastService();
// 监听登出事件
const off = broadcast.on('logout', () => {
router.push('/login');
});
// 广播登出(通知所有标签)
broadcast.postMessage('logout');
// 组件卸载时移除监听
onUnmounted(() => off());十八、国际化 i18n
locale(instance)
注入 vue-i18n 实例,同时合并内置中英文语言包(不覆盖宿主已有翻译)。
// main.ts
import { locale } from '@pit-frontend-framework/utils';
import i18n from '@/i18n';
locale(i18n);
app.use(i18n);t(key, fallback?)
翻译 key,优先使用已注入的 i18n,降级到内置语言包(中文)。
import { t } from '@pit-frontend-framework/utils';
t('validate.longitude', '请输入正确的经度值');getI18nInstance() / setI18nInstance(instance?)
获取/设置当前 i18n 实例,setI18nInstance(undefined) 同时重置消息解析器。
十九、JWKS 加密 jwks
getJwks(value, jwksPath, options?)
使用 RSA 公钥(JWKS 协议)加密字符串,常用于登录密码加密。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| value | string | 待加密的值(如明文密码) |
| jwksPath | string | JWKS endpoint URL |
| options.kid | string | 指定 kid(覆盖全局配置) |
| options.fetcher | (url) => Promise<Response> | 自定义 fetch 函数(测试/代理) |
| options.jwks | { keys: JwksKey[] } | 预置 JWKS 数据(跳过网络请求) |
- 返回值:
Promise<string>— RSA 加密后的密文
import { getJwks, setJwksConfig, DEFINE_JWKS_PATH, DEFINE_JWKS_KID } from '@pit-frontend-framework/utils';
// 全局配置 kid(只需执行一次)
setJwksConfig({ kid: DEFINE_JWKS_KID });
const encryptedPassword = await getJwks(password, DEFINE_JWKS_PATH);二十、本地缓存工具 localCache
URL 参数解析
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| getQueryString | () => Record<string, string> | 解析当前页面 URL 全部查询参数 |
| getKeyByUrl | (key: string) => string \| Record<string, string> | 获取单个查询参数值,key 为空则返回全部 |
常用 localStorage 读取
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| getProjectId | () => string \| Record<string, string> | 从 URL 取 projectId |
| getMajorId | () => string \| Record<string, string> | 从 URL 取 majorId |
| getUserId | () => string | 从 localStorage 取 userId |
| getBidId | () => string | 从 localStorage 取 bidId |
| getTaskStatus | () => string | 从 localStorage 取 taskStatus |
二十一、滚动工具 scroll
scrollTo(to, duration?, callback?)
平滑滚动到页面指定位置(easeInOutQuad 缓动)。
| 参数 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| to | number | — | 目标 scrollTop 值(px) |
| duration | number | 300 | 动画时长(ms),0 为立即跳转 |
| callback | () => void | — | 滚动完成回调 |
import { scrollTo } from '@pit-frontend-framework/utils';
scrollTo(0, 400, () => console.log('已滚动到顶部'));二十二、表格列宽 tableSize
createTableSize(size?)
根据表格密度生成列宽和对齐配置常量。
| 参数 | 类型 | 说明 |
| :--- | :--- | :--- |
| size | 'default' \| 'large' \| 'small' | 表格密度,默认 'default' |
- 返回值:
TableSizeType,包含DATE_WIDTH、OPERATION_ONE_WIDTH等预设列宽常量。
TABLE_SIZE(全局单例)
默认密度的表格列宽单例,直接引入使用:
import { TABLE_SIZE } from '@pit-frontend-framework/utils';
// main.ts 中挂载到全局属性
app.config.globalProperties.$TABLE_SIZE = TABLE_SIZE;在模板中:
<el-table-column label="日期" :width="$TABLE_SIZE.DATE_WIDTH" :align="$TABLE_SIZE.DATE_ALIGN" />二十三、通用校验 validate
| 函数 | 签名 | 说明 |
| :--- | :--- | :--- |
| isExternal | (path) => boolean | 是否为外部链接(http/https/mailto/tel) |
| validURL | (url) => boolean | 是否为合法 URL |
| validEmail | (email) => boolean | 是否为合法邮箱 |
| isString | (val) => val is string | 类型守卫:string |
| isArray | (val) => val is unknown[] | 类型守卫:array |
| islongitude | (rule, value, callback) | el-form-item 经度校验(-180 ~ 180) |
| islatitude | (rule, value, callback) | el-form-item 纬度校验(-90 ~ 90) |
import { islongitude, islatitude } from '@pit-frontend-framework/utils';
const rules = {
longitude: [{ validator: islongitude }],
latitude: [{ validator: islatitude }],
};二十四、页面工具 page
getPageTitle(routeKey?, pageTitle?)
构建 "页面名称 - 应用标题" 格式的浏览器标签标题(常用于路由守卫)。
import { getPageTitle } from '@pit-frontend-framework/utils';
// 在路由守卫中
document.title = getPageTitle(undefined, route.meta.title as string);setDefaultAppTitle(title) / setAppTitleResolver(fn)
自定义默认应用标题或通过解析函数动态获取(如从 store 读取)。
二十五、组件安装 install
withInstall<T>(component, alias?)
为 Vue 组件添加 install 方法,使其可以 app.use() 注册。
import { withInstall } from '@pit-frontend-framework/utils';
import MyComp from './MyComp.vue';
export const MyComponent = withInstall(MyComp);
// app.use(MyComponent) 或 app.component('MyComp', MyComponent)definePropType<T>(val)
类型安全的 PropType<T> 辅助函数,避免 as PropType<T> 硬转型。
二十六、pit 业务集合 pit
聚合权限、流程、存储等常用操作的业务工具对象,对应旧版
pit-business-utils。
import { pit } from '@pit-frontend-framework/utils';
// 权限
pit.hasP('module:list');
pit.hasBtnP('btn_add');
pit.hasFormP('field_name');
pit.adminAuthority();
pit.isProjectManager();
// 流程:根据审批状态和 writeable 标志判断是否可编辑
pit.hasFlow(params, hasFlowFlag);
// 数字格式化
pit.formatFloat('1234.567', 2);
pit.amountThousandsConversion(1234567.89); // '1,234,567.89'
// 日期
pit.toDate(new Date(), 'yyyy-MM-dd');
pit.dateFormat(date, 'YYYY-MM-DD');
pit.dateDiff('2026-01-01', '2026-04-29'); // 118
// 树
pit.treeToArray(treeData);
pit.arrayToTree(flatData);
pit.iterationArr(treeData, (node) => { /* ... */ });
// 文件
pit.formatFileSize(1048576); // '1.00 MB'
pit.getBlobFileName(response);pit.hasCode 预置按钮编码常量:
btn_add / btn_edit / btn_detail / btn_remove / btn_batchRemove / btn_copy / btn_upload / btn_download / btn_more / btn_grading / btn_password / btn_menu / btn_relation / btn_batchXZ / btn_class / btn_reduction / btn_del / btn_autoSC / btn_batchFB / btn_sum / btn_unlock / btn_estimate
二十七、全局常量 constants
| 常量 | 类型 | 说明 |
| :--- | :--- | :--- |
| IS_OK | '00000' | 接口成功响应码 |
| BIDTYPE.JL | 'JL' | 监理标 |
| BIDTYPE.SG | 'SG' | 施工标 |
| BIDTYPE.SJ | 'SJ' | 设计标 |
| BIDTYPE.ZX | 'ZX' | 咨询标 |
import { IS_OK, BIDTYPE } from '@pit-frontend-framework/utils';
if (response.code === IS_OK) {
// 请求成功
}最佳实践:main.ts 启动序列
import { createApp } from 'vue';
import {
initAppConfigFromViteEnv,
setRouteResolver,
setPermissionContext,
locale,
setRequestHooks,
} from '@pit-frontend-framework/utils';
import router from '@/router';
import i18n from '@/i18n';
import { useUserStore } from '@/store';
// 1. 最先初始化配置(其他模块依赖此步骤)
initAppConfigFromViteEnv(import.meta.env);
// 2. 注入路由上下文
setRouteResolver(() => router.currentRoute.value);
// 3. 注入权限上下文(惰性解析,pinia 初始化后安全调用)
setPermissionContext({
getPermissionList: () => useUserStore().permissionList,
getModelId: () => String(router.currentRoute.value.meta.modelId ?? ''),
});
const app = createApp(App);
setupStore(app);
app.use(router);
app.use(i18n);
// 4. 注入 i18n 实例(合并内置语言包)
locale(i18n);
app.mount('#app');Peer Dependencies
| 包 | 版本 | 说明 |
| :--- | :--- | :--- |
| vue | ^3.0.0 | Vue 3 核心 |
| axios | ^1.15.0 | HTTP 请求 |
| dayjs | ^1.11.1 | 日期处理 |
| mitt | ^3.0.0 | 事件总线 |
| jsrsasign | ^10.9.0 | JWKS 加密(按需) |
| qs | ^6.11.2 | 参数序列化 |
| lodash-es | ^4.17.21 | 部分工具函数 |
