API 参考

nb.pubfn 公共函数库

参考 vk-unicloud 设计的工具函数库

时间处理 · 数据校验 · 数组操作 · 树形结构


🎯 概述

nb.pubfn 是 NextJS Base 的公共函数库,参考 vk-unicloud 的 pubfn API 设计,提供统一的工具函数。

使用方式

import nb from '@/lib/function'

// 使用示例
nb.pubfn.isNull(value)
nb.pubfn.timeFormat(new Date())
nb.pubfn.tree.arrayToTree(list)

📚 API 目录

分类函数
时间处理timeFormat, getDateInfo, getCommonTime, sleep
数据校验isNull, isNotNull, test, validator
类型判断isArray, isObject, isString, getType
对象操作deepClone, getData, setData, formAssign
数组操作getListItem, arrayUnique, arraySort, groupBy
树形结构arrayToTree, treeToArray, mapTree, findInTree
字符串处理hidden, random, trim, truncate
编码转换uuid, encodeBase64, parseJSON
数学计算formatMoney, priceFilter, toDecimal
函数工具debounce, throttle, batchRun

⏰ 时间处理

timeFormat - 日期格式化

nb.pubfn.timeFormat(date, format, targetTimezone)
参数类型默认值说明
dateDate/Number/String-日期对象、时间戳或字符串
formatString'yyyy-MM-dd hh:mm:ss'格式化模板
targetTimezoneNumber8目标时区

格式化占位符yyyy(年), MM(月), dd(日), hh(时), mm(分), ss(秒), S(毫秒)

nb.pubfn.timeFormat(new Date(), 'yyyy-MM-dd')
// "2025-12-03"

nb.pubfn.timeFormat(1733136000000, 'yyyy年MM月dd日 hh:mm')
// "2025年12月02日 18:00"

getDateInfo - 解析日期

const info = nb.pubfn.getDateInfo(new Date())
// { year: 2025, month: 12, day: 3, hour: 10, minute: 30, second: 0, week: 3, quarter: 4 }

getCommonTime - 常用时间范围

const time = nb.pubfn.getCommonTime()
// { todayStart, todayEnd, monthStart, monthEnd, yearStart, yearEnd, weekStart, weekEnd, now }

sleep - 休眠等待

await nb.pubfn.sleep(1000)  // 等待 1 秒

✅ 数据校验

isNull / isNotNull - 空值判断

以下值被视为空:undefined, null, "", {}, []

nb.pubfn.isNull(null)       // true
nb.pubfn.isNull('')         // true
nb.pubfn.isNull({})         // true
nb.pubfn.isNull([])         // true
nb.pubfn.isNull(0)          // false
nb.pubfn.isNotNull('hello') // true

isNullOne / isNullAll / isNotNullAll - 批量判断

nb.pubfn.isNullOne(a, b, c)     // 至少一个为空
nb.pubfn.isNullAll(a, b, c)     // 全部为空
nb.pubfn.isNotNullAll(a, b, c)  // 全部不为空

test - 格式校验

type说明
mobile手机号
email邮箱
url网址
ipIP 地址
card身份证
number纯数字
chinese纯中文
password密码 (6-18位)
nb.pubfn.test('13800138000', 'mobile')  // true
nb.pubfn.test('[email protected]', 'email')  // true

🔍 类型判断

nb.pubfn.isArray([1, 2, 3])      // true
nb.pubfn.isObject({ a: 1 })      // true
nb.pubfn.isString('hello')       // true
nb.pubfn.isNumber(123)           // true
nb.pubfn.isFunction(() => {})    // true
nb.pubfn.isDate(new Date())      // true

nb.pubfn.getType([])             // 'array'
nb.pubfn.getType({})             // 'object'
nb.pubfn.getType(null)           // 'null'

📦 对象操作

deepClone - 深度克隆

const newObj = nb.pubfn.deepClone(obj)

getData / setData - 路径取值/设值

const obj = { a: { b: { c: 1 } } }

nb.pubfn.getData(obj, 'a.b.c')           // 1
nb.pubfn.getData(obj, 'a.b.d', 'default') // 'default'

nb.pubfn.setData(obj, 'a.b.c', 2)
nb.pubfn.setData(obj, 'x.y.z', 3)  // 自动创建路径

formAssign - 表单数据填充

const defaultData = { name: '', age: 0, enable: true }
const itemData = { name: '张三', age: 25 }

const formData = nb.pubfn.formAssign(defaultData, itemData)
// { name: '张三', age: 25, enable: true }

getNewObject / deleteObjectKeys

const obj = { id: 1, name: '张三', password: '123' }

nb.pubfn.getNewObject(obj, ['id', 'name'])  // { id: 1, name: '张三' }
nb.pubfn.deleteObjectKeys(obj, ['password']) // { id: 1, name: '张三' }

📋 数组操作

getListItem - 获取数组中的对象

const list = [
  { id: 1, name: '张三' },
  { id: 2, name: '李四' }
]

nb.pubfn.getListItem(list, 'id', 2)  // { id: 2, name: '李四' }
nb.pubfn.getListIndex(list, 'id', 2) // 1

arrayToJson - 数组转对象

const list = [
  { id: 'a', name: '张三' },
  { id: 'b', name: '李四' }
]

nb.pubfn.arrayToJson(list, 'id')
// { a: { id: 'a', name: '张三' }, b: { id: 'b', name: '李四' } }

arrayObjectGetArray - 提取字段

nb.pubfn.arrayObjectGetArray(list, 'id')  // ['a', 'b']

arrayUnique - 数组去重

nb.pubfn.arrayUnique([1, 2, 2, 3])  // [1, 2, 3]
nb.pubfn.arrayUnique([{id:1},{id:2},{id:1}], 'id')  // [{id:1},{id:2}]

arraySort - 数组排序

nb.pubfn.arraySort([3, 1, 2])  // [1, 2, 3]
nb.pubfn.arraySort([{age:30},{age:20}], 'age', 'desc')  // [{age:30},{age:20}]

arrayDiff / arrayIntersect / arrayUnion - 集合运算

nb.pubfn.arrayDiff([1,2,3], [2,3,4])       // [1] (差集)
nb.pubfn.arrayIntersect([1,2,3], [2,3,4])  // [2,3] (交集)
nb.pubfn.arrayUnion([1,2,3], [2,3,4])      // [1,2,3,4] (并集)

groupBy - 分组

const list = [
  {type:'a', v:1},
  {type:'b', v:2},
  {type:'a', v:3}
]
nb.pubfn.groupBy(list, 'type')
// { a: [{type:'a',v:1},{type:'a',v:3}], b: [{type:'b',v:2}] }

sum / average / max / min - 统计

nb.pubfn.sum([1, 2, 3])       // 6
nb.pubfn.average([1, 2, 3])   // 2
nb.pubfn.max([1, 2, 3])       // 3
nb.pubfn.min([1, 2, 3])       // 1

nb.pubfn.sum([{v:1},{v:2}], 'v')  // 3

shuffle / sample - 随机

nb.pubfn.shuffle([1, 2, 3, 4, 5])      // 随机打乱
nb.pubfn.sample([1, 2, 3, 4, 5])       // 随机取一个
nb.pubfn.sampleSize([1, 2, 3, 4, 5], 3) // 随机取3个

🌳 树形结构

所有树形工具在 nb.pubfn.tree 下。

arrayToTree - 数组转树

nb.pubfn.tree.arrayToTree(arr, options)
参数类型默认值说明
idString'id'主键字段
parentIdString'parentId'父级字段
childrenString'children'子节点字段
rootParentIdanynull根节点 parentId
filterFunction-过滤函数
sortByArray-排序配置
const list = [
  { id: 1, parentId: null, name: '系统管理' },
  { id: 2, parentId: 1, name: '用户管理' },
  { id: 3, parentId: 1, name: '角色管理' },
]

const tree = nb.pubfn.tree.arrayToTree(list, {
  filter: (item) => item.enable !== false,
  sortBy: [{ field: 'sort', order: 'asc' }]
})

treeToArray - 树转数组

nb.pubfn.tree.treeToArray(tree, { addLevel: true })
// [{ id: 1, name: 'A', level: 0 }, { id: 2, name: 'B', level: 1 }, ...]

mapTree - 映射树

const selectTree = nb.pubfn.tree.mapTree(menuTree, (node) => ({
  title: node.name,
  value: node.id,
  key: node.id,
}))

findInTree - 查找节点

const node = nb.pubfn.tree.findInTree(tree, (item) => item.id === 'menu-1')

filterTree - 过滤树

const filtered = nb.pubfn.tree.filterTree(tree, (item) => 
  item.name.includes('用户')
)

getLeaves - 获取叶子节点

const leaves = nb.pubfn.tree.getLeaves(tree)

📝 字符串处理

hidden - 隐藏中间字符

nb.pubfn.hidden('13800138000', 3, 4)  // '138****8000'

random - 随机字符串

nb.pubfn.random(6)                // '123456' (纯数字)
nb.pubfn.random(8, 'a-z,0-9')     // 'a1b2c3d4'
nb.pubfn.random(10, 'a-z,A-Z,0-9') // 'aB1cD2eF3g'

trim / truncate

nb.pubfn.trim('  hello  ')         // 'hello'
nb.pubfn.truncate('hello world', 8) // 'hello...'

capitalize / uncapitalize

nb.pubfn.capitalize('hello')    // 'Hello'
nb.pubfn.uncapitalize('Hello')  // 'hello'

🔐 编码转换

uuid / shortUuid

nb.pubfn.uuid()       // 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
nb.pubfn.shortUuid()  // 'a1b2c3d4' (8位)

encodeBase64 / decodeBase64

nb.pubfn.encodeBase64('hello')     // 'aGVsbG8='
nb.pubfn.decodeBase64('aGVsbG8=')  // 'hello'

parseJSON / stringifyJSON

nb.pubfn.parseJSON('{"a":1}')      // { a: 1 }
nb.pubfn.parseJSON('invalid', {})  // {} (解析失败返回默认值)

💰 数学计算

formatMoney - 千分位格式化

nb.pubfn.formatMoney(1234567.89)     // '1,234,567.89'
nb.pubfn.formatMoney(1234567.89, 0)  // '1,234,568'

priceFilter - 分转元

nb.pubfn.priceFilter(100)   // '1.00'
nb.pubfn.priceFilter(1234)  // '12.34'

toDecimal - 保留小数

nb.pubfn.toDecimal(1.56555, 2)  // 1.57

🔧 函数工具

debounce - 防抖

nb.pubfn.debounce(() => {
  // 执行搜索
}, 300)

throttle - 节流

nb.pubfn.throttle(() => {
  // 执行操作
}, 1000)

batchRun - 并发执行

const tasks = [
  () => fetch('/api/1'),
  () => fetch('/api/2'),
]
const results = await nb.pubfn.batchRun(tasks, 2)  // 最多同时执行2个

✅ 最佳实践

1. 类型判断优先使用 nb.pubfn

// ✅ 推荐
if (nb.pubfn.isArray(value)) { }
if (nb.pubfn.isNull(data)) { }

// ❌ 不推荐
if (Array.isArray(value)) { }
if (!data || data === '') { }

2. 树形数据使用 tree 工具

// ✅ 推荐
const tree = nb.pubfn.tree.arrayToTree(list)
const node = nb.pubfn.tree.findInTree(tree, predicate)

// ❌ 不推荐:手写递归
function buildTree(list, parentId = null) { ... }

3. ID 生成统一使用 uuid

// ✅ 推荐
const id = nb.pubfn.uuid()

// ❌ 不推荐
import { v4 as uuidv4 } from 'uuid'

📚 相关文档