Skip to content

一个循环解决行转树的问题,快速,轻量,无依赖。

License

Notifications You must be signed in to change notification settings

zhengxs2018/js.tree

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation



👍
@zhengxs/js.tree



TypeScript code style: prettier npm package npm downloads npm downloads Gzip Size Cypress codecov Github action Typings License

快速,轻量,无依赖的树结构数据处理函数库。




  • 一个循环解决行转树的问题
  • 转树除了添加 children 属性,不会修改任何数据
  • 支持任意关系字段,如:非 id,parentId, children 字段支持
  • 支持接管插入行为,如:自定义插入顺序
  • 支持动态导出树节点
  • 内置 filter/map 函数

快速开始

国内镜像

文档

安装

$ npm i @zhengxs/js.tree --save

使用

import { toTree } from '@zhengxs/js.tree'

toTree([
  { id: 10000, parentId: null, title: '标题 1' },
  { id: 20000, parentId: null, title: '标题 2' },
  { id: 11000, parentId: 10000, title: '标题 1-1' },
])
// ->
// [
//   {
//     id: 10000,
//     parentId: null,
//     title: '标题 1',
//     children: [
//       { id: 11000, parentId: 10000, title: '标题 1-1', children: [] }
//     ]
//   },
//   { id: 20000, parentId: null, title: '标题 2', children: [] },
// ]

支持任意关系字段的数据

import { toTree, ROOT_ID } from '@zhengxs/js.tree'

const data = [
  { uid: 10000, pid: null, title: '标题 1', sort: 1 },
  { uid: 20000, pid: null, title: '标题 2', sort: 2 },
  { uid: 11000, pid: 10000, title: '标题 1-1', sort: 3 },
]

const result = toTree(data, {
  // 如果 parentId 为 null 或 undefined 会合并一起
  // 使用 ROOT_ID 作为 key 保存
  // 支持函数,动态返回
  root: ROOT_ID,

  // lodash 版本,支持 path, 如: nested.id
  idKey: 'uid', // 可选,默认: id

  // lodash 版本,支持 path, 如: nested.parentId
  parentKey: 'pid', // 可选,默认:parentId

  // 挂载子级的属性名称,默认:children
  childrenKey: 'items',

  // 数据添加进 children 数组前的处理,可选
  transform(data) {
    // 通过浅拷贝避免修改原始数据
    // 可以在这里动态添加属性
    return { ...data, checked: false }
  },

  // 接管插入行为
  insert(siblings, node) {
    // ps: 任意层级的数据都是这样处理的
    const index = siblings.findIndex((n) => n.sort > node.sort)

    if (index === -1) {
      siblings.push(node)
    } else {
      siblings.splice(index, 0, node)
    }
  },
})
// ->
// [
//   {
//     uid: 10000,
//     pid: null,
//     title: '标题 1',
//     sort: 1,
//     checked: false,
//     items: [
//       {
//         uid: 11000,
//         pid: 10000,
//         title: '标题 1-1',
//         sort: 3,
//         checked: false,
//         items: []
//       }
//     ]
//   },
//   {
//     uid: 20000,
//     pid: null,
//     title: '标题 2',
//     sort: 2,
//     checked: false,
//     items: []
//   }
// ]

Try in runkit

TypeScript

内置 ts 类型

import { toTree } from '@zhengxs/js.tree'

// 转换前的数据
type MenuItem = {
  id: string
  parentId: string
  text: string
  url?: string
}

// 转换后的数据
interface Nav extends MenuItem {
  items: Nav[]
}

// 如果修改了 childrenKey
// 为了让类型提示正确,可以传入正确的类型
toTree<Nav>(source, {
  childrenKey: 'items',
})

对不同构建版本的解释

umd 模块使用 es5,其他版本使用的是 es2015

在包的 dist/ 目录你将会找到很多不同的构建版本,这里列出了它们之间的差别:

UMD CommonJS ES Module
无依赖 js.tree.js js.tree.common.js js.tree.esm.js
无依赖(生产环境) js.tree.min.js
包含 lodash 模块 js.tree.common.lodash.js js.tree.esm.lodash.js
包含 lodash-es 模块 js.tree.esm.lodash-es.js

除环境导致的,为了减少包体积,和项目共享 lodash 模块。

但不是所有项目都会引入,为了避免这种情况,默认的都是不带的。

其他

License

  • MIT