tools_dj
v1.0.88
Published
dj tools 工具库
Readme
DJ 工具库
一个全面的 JavaScript/TypeScript 工具函数集合,包含数据处理、时间格式化、树结构操作、DOM 操作等常用功能。
安装
npm install tools_dj使用
基础使用
import { formatDate, is_empty, formatSize } from "tools_dj";
// 格式化日期
const date = formatDate(new Date(), 'day', '-'); // "2024-03-24"
// 检查空值
const isEmpty = is_empty(""); // true
// 格式化文件大小
const size = formatSize(1024); // "1 KB"使用类模块
// 权限管理
import { auth } from "tools_dj";
const authManager = new auth(['read', 'write', 'delete']);
// 时间比较
import { carbon } from "tools_dj";
const timeCheck = carbon(new Date());
// HTTP请求
import Request from "tools_dj/request";
const http = new Request({
headers: { 'Content-Type': 'application/json' }
}, { baseUrl: 'https://api.example.com' });API 文档
数据类型判断
is(obj: any): string
判断数据类型,返回具体类型名称
is([1, 2, 3]); // "Array"
is({}); // "Object"
is("hello"); // "String"is_empty(obj: any): boolean
判断值是否为空,支持所有数据类型
is_empty(null); // true
is_empty(""); // true
is_empty([]); // true
is_empty({}); // trueisNum(data: any): boolean
判断是否是数字(包括字符型数字)
isNum("123"); // true
isNum(456); // true
isNum("abc"); // false数组操作
del_repeat(obj: any[]): any[]
删除数组重复元素
del_repeat([1, 2, 2, 3]); // [1, 2, 3]unique(obj: any[]): any[] | false
去除数组重复元素(带空值检查)
unique([1, 2, 2, 3]); // [1, 2, 3]first(obj: any): any
获取数组或对象的第一个元素
first([1, 2, 3]); // 1last(obj: any): any
获取数组或对象的最后一个元素
last([1, 2, 3]); // 3arrayGroup(arr: any[], groupKey: string): object
数组分组
arrayGroup([{type: 'A', value: 1}, {type: 'B', value: 2}], 'type');
// { A: [{type: 'A', value: 1}], B: [{type: 'B', value: 2}] }时间处理
formatDate(time: Date, format: string, type: string): string
格式化时间
formatDate(new Date(), 'day', '-'); // "2024-03-24"
formatDate(new Date(), 'minute', '/'); // "2024/03/24/14/30"formatTime(time: any, format: string, option?: object): string
高级时间格式化
formatTime('2024-03-24', 'YYYY年MM月DD日'); // "2024年03月24日"
formatTime(new Date(), 'YYYY-MM-DD week'); // "2024-03-24 周日"getDaysBetween(date1: string, date2: string, negative?: boolean): number
计算两个日期之间的天数
getDaysBetween('2024-01-01', '2024-01-05'); // 4isDateInRange(date: string, startDate: string, endDate: string): boolean
判断日期是否在指定范围内
isDateInRange('2024-02-15', '2024-01-01', '2024-12-31'); // true对象操作
merge(obj1: any, obj2: any): any
合并数组或对象
merge([1, 2], [3, 4]); // [1, 2, 3, 4] (去重后)
merge({a: 1}, {b: 2}); // {a: 1, b: 2}delObj(obj: object, keys?: string | string[]): void
删除对象属性
const obj = {a: 1, b: 2, c: 3};
delObj(obj, 'a'); // {b: 2, c: 3}
delObj(obj, ['b', 'c']); // {}delObjEmptyKey(obj: object): void
删除对象中的空属性
const obj = {a: 1, b: '', c: null, d: 2};
delObjEmptyKey(obj); // {a: 1, d: 2}树结构操作
arrToTree(data: any[], option?: object): any[]
平级数组转树形结构
const data = [
{id: 1, parentId: 0, name: 'root'},
{id: 2, parentId: 1, name: 'child1'}
];
arrToTree(data); // 树形结构treeToArr(data: any[], option?: object): any[]
树形结构转平级数组
treeToArr(treeData); // 扁平化数组handleTree(data: any[], id: string, parentId: string, children: string): any[]
构造树形结构数据
handleTree(data, 'id', 'parentId', 'children');字符串处理
toGetQuery(data: object, option?: object): string
对象转URL查询参数
toGetQuery({name: 'test', age: 20}); // "?name=test&age=20"isLink(str: string): boolean
判断字符串是否为有效链接
isLink('https://example.com'); // true
isLink('not-a-link'); // falserepalce(str: string, index: number, char: string): string
字符串指定位置替换
repalce('hello', 1, 'a'); // "hallo"数字处理
formatSize(num: number, option?: object): string
转换大小默认是文件可以是别的
formatSize(1024); // "1 KB"
formatSize(1048576, {decimals: 1}); // "1.0 MB"numberFixed(number: number, decimalPlaces?: number): number
数字保留小数位(截取不四舍五入)
numberFixed(3.14159, 2); // 3.14numberRepair(str: string, n: number, k: string, d: boolean): string
数字前置补位
numberRepair('5', 3, '0'); // "005"randomNumber(min: number, max: number): number
生成随机数
randomNumber(1, 100); // 1-100之间的随机数工具函数
throttle(fn: Function, delay?: number, immediate?: boolean): Function
节流函数
const throttled = throttle(() => console.log('throttled'), 1000);debounce(fn: Function, delay: number): Function
防抖函数
const debounced = debounce(() => console.log('debounced'), 300);memoize(func: Function, options?: object): Function
函数缓存
const cachedFn = memoize(expensiveFunction, {ttl: 5000});DOM 相关
isMobile(): boolean
检测是否为移动设备
isMobile(); // true/falsesetMeta(meta: object): void
设置页面meta信息
setMeta({title: "页面标题", cZoom: {mobile: 0.8}});转换工具
pxToRem(pxValue: string | number, baseRem?: number): string
px转rem
pxToRem('16px'); // "0.43rem"
pxToRem(32, 16); // "2.00rem"base64Img(base64: string, imgName: string): File
base64转文件对象
const file = base64Img(base64String, 'image.png');objToFormData(obj: object, simplify?: boolean): FormData
对象转FormData
obj- 要转换的对象simplify- 是否简化(简化后第一层数组将省略索引),默认true
const formData = objToFormData({name: 'test', files: [file1, file2]});数组高级操作
findByIndex(array: any[], key: string, data: any): number
二维数组查找返回下标
const users = [{id: 1, name: 'Tom'}, {id: 2, name: 'Jerry'}];
findByIndex(users, 'id', 2); // 1setObjData(source: any[], sourceKey: string, sourceData: any, nowKey: string, nowData: any): boolean
设置二维数组的值
const data = [{id: 1, name: 'old'}];
setObjData(data, 'id', 1, 'name', 'new'); // true
// data: [{id: 1, name: 'new'}]selectObjData(source: any[], sourceKey: string, sourceData: any): any
查找二维数组数据
const users = [{id: 1, name: 'Tom'}, {id: 2, name: 'Jerry'}];
selectObjData(users, 'id', 2); // {id: 2, name: 'Jerry'}arrSet(arr: any[], index: number, data: any): void
在数组任意位置插入数据
const arr = [1, 2, 4];
arrSet(arr, 2, 3); // [1, 2, 3, 4]sArrMove(arr: any[], startIndex: number, endIndex: number): void
源数组移动元素(直接修改原数组)
const arr = [1, 2, 3, 4];
sArrMove(arr, 0, 2); // arr变为 [2, 3, 1, 4]rArrMove(arr: any[], startIndex: number, endIndex: number): any[]
数组元素位置移动返回新数组(不修改原数组)
const arr = [1, 2, 3, 4];
const newArr = rArrMove(arr, 0, 2); // [2, 3, 1, 4]
// arr仍为 [1, 2, 3, 4]inArr(arr: any[], str: any, force?: boolean): number
判断字符是否在数组中,返回索引
force- 是否强制类型检查,默认false(使用==比较)
inArr([1, 2, 3], '2'); // 1 (非强制模式)
inArr([1, 2, 3], '2', true); // -1 (强制模式)树结构高级操作
treeFor(data: any[], callBack: Function, option?: object): void
树循环返回子项(叶子节点)
option.cKey- 子节点字段名,默认'children'
treeFor(treeData, (node) => {
console.log('叶子节点:', node);
});treeStack(data: any[], callBack: Function, option?: object): void
树栈循环返回子项
treeStack(treeData, (node) => {
console.log('节点:', node);
});treeRecursion(data: any[], callBack: Function, option?: object): void
树递归循环返回子项
treeRecursion(treeData, (node) => {
console.log('节点:', node);
});treeFind(data: any[], option?: object): any[]
树中查找节点
option.cKey- 子节点字段名,默认'children'option.key- 查找的字段名,默认'id'option.value- 查找的值option.copy- 是否复制(去除children),默认true
treeFind(treeData, {key: 'id', value: 5});arrToAryTree(items: any[], option?: object): any[]
层级树转换成多叉树(带左右值的嵌套集合模型)
option.idKey- ID字段,默认'id'option.pidKey- 父ID字段,默认'pid'option.rKey- 右值字段,默认'rgt'option.lKey- 左值字段,默认'lft'option.levelKey- 层级字段,默认'level'
const tree = arrToAryTree(flatData);
// 返回带有lft、rgt、level字段的数组颜色处理
colorMix(color1: string, color2: string, weight: number): string
色阶取值(颜色混合)
weight- 权重0-1,越接近1越接近color2
colorMix('#ff0000', '#0000ff', 0.5); // "#7f007f" (混合紫色)randomColor(): string
生成随机颜色(rgba格式)
randomColor(); // "rgba(150,200,180,1)"排序
compare(prop: string, type?: string): Function
数字排序比较函数
type- 'up'升序(默认)或'down'降序
const users = [{age: 25}, {age: 18}, {age: 30}];
users.sort(compare('age', 'up')); // 按age升序compareDate(prop: string, type?: string): Function
时间排序比较函数
const events = [
{date: '2024-03-20'},
{date: '2024-01-15'}
];
events.sort(compareDate('date', 'up')); // 按日期升序函数工具
throttle1(func: Function, delay: number): Function
节流函数(备选实现)
const throttled = throttle1(() => {
console.log('执行');
}, 1000);fnRuntime(fn: Function, iterations?: number): void
测量函数执行时间
iterations- 迭代次数,默认1
fnRuntime(() => {
// 需要测试的代码
}, 100);
// 控制台输出: "平均执行时间 100 次数: 0.123456 ms"mergeObj(obj: object[], callbackCon?: object): object
深层次对象合并
callbackCon.callback- 回调函数callbackCon.callType- 回调类型callbackCon.afterBack- 后置回调
const merged = mergeObj([
{a: {b: 1}},
{a: {c: 2}}
]);
// {a: {b: 1, c: 2}}其他工具
time_change(data: string): number
时间格式转时间戳
time_change('2024-03-24 10:30'); // 1711252200000类模块
权限管理 (auth)
基于位运算的高性能权限管理系统
import { auth } from "tools_dj";
// 创建权限管理实例
const authManager = new auth(['read', 'write', 'delete', 'update']);
// 初始权限为0
let userAuth = 0;
// 添加权限
userAuth = authManager.add(userAuth, ['read', 'write']);
// 删除权限
userAuth = authManager.del(userAuth, ['write']);
// 判断权限(必须全部存在)
authManager.andHave(userAuth, ['read', 'write']); // false
// 判断权限(只要有一个存在)
authManager.orHave(userAuth, ['read', 'write']); // true
// 获取权限列表
authManager.getTxt(userAuth); // ['read']API说明:
constructor(authList: string[])- 创建权限管理实例add(base: number, arr: string[]): number- 添加权限del(base: number, arr: string[]): number- 删除权限andHave(base: number, arr: string[]): boolean- AND判断(全部存在)orHave(base: number, arr: string[]): boolean- OR判断(至少一个存在)getTxt(number: number): string[]- 获取权限名称列表
时间比较 (date)
提供链式时间比较操作
import { carbon, contrast } from "tools_dj";
// 方式1: 使用carbon函数
const timeCheck = carbon(new Date('2024-03-24'));
// 方式2: 使用contrast类
const timeCheck2 = new contrast(new Date('2024-03-24'));
// 大于
timeCheck.Gt(new Date('2024-03-20')); // true
// 小于
timeCheck.Lt(new Date('2024-03-30')); // true
// 等于
timeCheck.Eq(new Date('2024-03-24')); // true
// 不等于
timeCheck.Ne(new Date('2024-03-25')); // true
// 大于等于
timeCheck.Gte(new Date('2024-03-24')); // true
// 小于等于
timeCheck.Lte(new Date('2024-03-24')); // true
// 判断是否在时间段内
timeCheck.Between(
new Date('2024-03-20'),
new Date('2024-03-30')
); // trueAPI说明:
Gt(date: Date): boolean- 大于Lt(date: Date): boolean- 小于Eq(date: Date): boolean- 等于Ne(date: Date): boolean- 不等于Gte(date: Date): boolean- 大于等于Lte(date: Date): boolean- 小于等于Between(date1: Date, date2: Date): boolean- 是否在时间段内
消息通信 (msg)
提供跨页面和页面内的消息通信
import msg from "tools_dj/msg";
// 跨页面消息发送(使用BroadcastChannel)
msg.pageSend('userUpdate', {id: 1, name: 'Tom'});
// 跨页面消息接收
msg.pageRead('userUpdate', (data) => {
console.log('收到消息:', data);
});
// 页面内消息发送(使用mitt)
msg.busSend('event1', {data: 'test'});
// 页面内消息接收
msg.busRead('event1', (data) => {
console.log('收到事件:', data);
});
// 取消特定监听器
const handler = (data) => console.log(data);
msg.busRead('event1', handler);
msg.busOff('event1', handler);
// 取消所有同名监听
msg.busDown('event1');
// store消息监听(适用于Vue的Pinia store)
msg.storeRead(store, (state) => {
console.log('store变化:', state);
});API说明:
pageSend(type: string, data: any): void- 跨页面消息发送pageRead(type: string, callback: Function): void- 跨页面消息接收busSend(type: string, data: any): void- 页面内消息发送busRead(type: string, callback: Function): void- 页面内消息接收busOff(type: string, callback: Function): void- 取消特定监听busDown(type: string): void- 取消所有同名监听storeRead(store: any, callback: Function): void- store变化监听
HTTP请求 (request)
基于Fetch API的HTTP请求封装
import Request from "tools_dj/request";
// 创建请求实例
const http = new Request(
// 默认请求配置
{
headers: {
'Content-Type': 'application/json'
},
mode: 'cors',
credentials: 'include'
},
// 全局配置
{
baseUrl: 'https://api.example.com',
timeout: 10000,
// 成功回调
callback: async (response) => {
return await response.json();
},
// 失败回调
errBack: (error) => {
console.error('请求失败:', error);
},
// 请求前回调
beforeBack: (options) => {
console.log('发送请求:', options);
},
// 获取中断控制器
abController: (controller) => {
// 可以手动中断请求
// controller.abort();
}
}
);
// 发送GET请求
http.serve('/users', {
method: 'GET'
}).then(data => {
console.log(data);
});
// 发送POST请求
http.serve('/users', {
method: 'POST',
body: JSON.stringify({name: 'Tom', age: 20})
}, {
// 单次请求配置
timeout: 5000,
callback: async (res) => await res.json()
}).then(data => {
console.log(data);
});
// 请求完整URL(会自动检测,不添加baseUrl)
http.serve('https://other-api.com/data');配置参数说明:
构造函数参数:
option- Fetch请求配置对象method- 请求方法 (GET, POST, PUT, DELETE等)mode- 跨域策略 ("cors", "same-origin", "no-cors")cache- 缓存策略 ("no-cache", "default", "reload", "force-cache")credentials- 凭证策略 ("same-origin", "include", "omit")headers- 请求头对象redirect- 重定向处理 ("follow", "manual", "error")referrerPolicy- 引用策略body- 请求体
conf- 全局配置对象baseUrl- 基础URL前缀timeout- 超时时间(毫秒),默认6000callback(response)- 成功回调,处理响应errBack(error)- 失败回调abController(controller)- 获取中断控制器beforeBack(options)- 请求前回调
serve方法参数:
url- 请求地址(相对路径或完整URL)options- 本次请求的fetch配置(会与构造函数的option合并)conf- 本次请求的配置(会与构造函数的conf合并)
特性
- 🚀 轻量高效 - 优化的算法实现
- 📦 TypeScript 支持 - 完整的类型定义
- 🔧 模块化设计 - 按需引入,减少包体积
- 🌍 跨平台兼容 - 支持浏览器和 Node.js 环境
- 📚 完整文档 - 详细的使用示例和API说明
许可证
MIT License
