Layui 19 treeTable 树组件(第 3 方扩展组件)

在这里插入图片描述
在这里插入图片描述

1、开始

【目标】layui 渲染 “树型数据”的实现方式。

【可实现效果】

【实现方式】github 搜索后结果
layui-treetable
treetable-lay

推荐使用 treetable-lay 库。

2.1、layui-treetable

layui-treetable 是一个 layui 树表实现的插件。
Gitee 文档

2.2、说明

说明
1、通过阅读这个包中的 layui 源码,这里是对 layui 进行的再开发,是将 treetable 当做原生模块注册的;

// ...
treetable: 'modules/treetable',

// ...
: (n.use(e, i), n)

2、layui 原生是不支持的,所以在自己的项目里需要将 treetable 作为第3方扩展模块注册。
3、且 css 是通过 js 追加的``,要改变为手动 link 标签引入。

// treetable.js
layui.addcss("modules/treetable/treetable.css") // 绝对路径添加 treetable.css 样式表

layui.link(layui.cache.base + '/treetable-lay/treetable.css'); // 可以用这个追加

2.3、处理

1、将 treetable 放入 layui 中;
在这里插入图片描述

2、手动引入 css;

/* https://gitcode.com/fangyinggui/study_code/blob/main/layui/19-1-1.html */
<link rel="stylesheet" href="/layui/extends_modules/layui-treetable/treetable.css" />

也可以类似库中的处理用 layui.addcss() 在当前页面添加。

3、作为第3方模块注册;

layui
  .config({
    base: '/layui/extends_modules',
  })
  .extend({
    treetable: '/layui-treetable/treetable',
  })
  .use(['form', 'treetable', 'layer'], function () {
    var layer = layui.layer,
      form = layui.form,
      $ = layui.jquery,
      treetable = layui.treetable

    console.log(1, '有没有treetable 模块?', treetable)

    var tree = layui.treetable({
      // ...
    })
  })

4、使用 treetable;

【示例】layui-treetable 渲染一个树表组件

2.4、api

tree.render()

【语法】

/**
 * @brief: 渲染一个树表
 * @param {Object} options 配置对象
 * @return {*} tree 返回一个树表实例
 */
var tree = treetable.render(options)

options 参数详细

【示例】这里

elem

【键】传入元素选择器;
【键值】{String}
例如: ‘#test1’

spreadable

设置是否全展开;
false (默认) 不展开

checkbox

是否显示复选框;
false (默认) 不显示复选框

layout

【键】自定义表头结构。
【键值】{Array} 一个集合
子项配置每一列;

  • name:渲染成表头单元格的名称;
  • treeNodes:
  • headerClass:设置列表头容器的类名;
  • colClass:设置列单元格容器的类名;
  • style:设置列样式(添加到 内联样式);

【注意】若显示复选框,在 .render() 调用后,需要手动调用 form.render() 渲染复选框。

nodes

【键】要渲染的节点数据。
【键值】{Array} 一个集合
子项配置每一列;

  • id {String} 唯一标志;
  • name {String} 节点名称;
  • spread {Boolean} 是否展开状态;(默认 false)
  • children {Object} 这个里面设置子节点;例如:children: [{name: '子节点',spread: true,children: [{name: '子子节点',children: [……]}]}, {……}]
  • checked {Boolean} 在 checkbox 配置项 为true的情况下,设置该节点是否勾选;

回调

【配置位置】所有回调都在 .redner(options) 参数的 callback 键值对象中配置。

【默认】不配置回调钩子,父节点都是允许被折叠和展开的。

treetable.render({
	callbacK: {
		// 在这里配置
	}
})

callback.beforeCheck

【语法】

/**
 * @brief: 用于 捕获勾选/取消勾选 之前的事件回调函数
 * @param {treeNode} node 进行勾选或取消勾选的节点 JSON 数据对象
 * @return {boolean} 根据返回值确定是否 允许勾选/取消勾选
 *    null (默认)返回值
 *    true 允许勾选
 *    false 将不会改变勾选状态,并且无法触发 onCheck 事件回调函数
 */
function treetableBeforeCheck(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    beforeCheck: treetableBeforeCheck,
  },
})

【示例】beforeCheck 和 onCheck

callback.onCheck

【语法】

/**
 * @brief: 用于 捕获checkbox被勾选 或 取消勾选的 事件回调函数
 * 【特殊】如果设置了 callback.beforeCheck 方法,且返回 false,将无法触发 onCheck 事件回调函数。
 * @param {treeNode} node 被勾选或取消勾选的 节点JSON数据对象
 * @return {boolean} 根据返回值确定是否 允许勾选/取消勾选
 *    null (默认)返回值
 *    true 允许勾选
 *    false 将不会改变勾选状态,并且无法触发 onCheck 事件回调函数
 */
function treetableOnCheck(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    beforeCheck: treetableOnCheck,
  },
})

【示例】beforeCheck 和 onCheck
【示例】beforeCheck 返回 false

【应用1】这里可以动态判断后,自定义复选框的勾选。

callback.beforeCollapse

【语法】

/**
 * @brief: 用于 捕获节点折叠之前 的事件回调函数
 * 【特殊】如果设置了 callback.beforeCollapse,且返回 false 或 null,将无法触发 onCollapse 事件回调函数。
 * @param {treeNode} node 被折叠的节点 JSON 数据对象
 * @return {boolean}
 *    null 将不会折叠节点!!
 *    true (默认)允许父节点折叠/展开
 *    false 将不会折叠节点,也无法触发 onCollapse 事件回调函数
 */
function treetableBeforeCollapse(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    beforeCollapse: treetableBeforeCollapse,
  },
})

【示例】beforeCollapse 和 onCollapse

callback.onCollapse

【语法】

/**
 * @brief: 用于 捕获节点被折叠 的事件回调函数
 * @param {treeNode} node 被折叠的节点 JSON 数据对象
 * @return {boolean} 这里返回值没什么效果
 */
function treetableOnCollapse(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    onCollapse: treetableOnCollapse,
  },
})

【示例】beforeCollapse 和 onCollapse
【示例】beforeCollapse 返回 false (切换注释)

callback.beforeExpand

【语法】

/**
 * @brief: 用于 捕获父节点展开之前 的事件回调函数
 * 【特殊】如果设置了 callback.beforeExpand 方法,且返回 false,将无法触发 onExpand 事件回调函数。
 * @param {JSON} node 被展开的节点 JSON 数据对象
 * @return {*} 这里返回值没什么效果
 */
function treetableBeforeExpand(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    beforeExpand: treetableBeforeExpand,
  },
})

【示例】beforeCollapse 和 onCollapse

callback.onExpand

【语法】

/**
 * @brief: 用于 捕获节点被展开 的事件回调函数
 * @param {JSON} node 被展开的节点 JSON 数据对象
 * @return {boolean} 根据返回值确定是否允许展开操作
 *    null /
 *    true /
 *    false /
 */
function treetableOnExpand(node) {
  return null
}

treetable.render({
  // ...
  callback: {
    onExpand: treetableOnExpand,
  },
})

【示例】beforeCollapse 和 onCollapse

2.5、实例方法

【原理】这些实例方法挂载在 treetable 的原型对象上。

var tree = layui.treetable(options);

【示例】treetable 实例对象

【tip】 下面的 tree 就是 treetable 实例化后的实例对象。

【示例】实例的一些方法

tree.collapse()

// 折叠(所有)菜单;
tree.collapse();

tree.collapseNode()

var node = tree.getNode("2");
/**
 * @brief: 折叠某个节点
 * @param {} node 节点信息
 * @param {} boolean
 * 		true:子节点跟随父节点一样折叠;
 * 		false:子节点不折叠;
 * @return {*}
 */
tree.collapseNode(node, boolean);

tree.expand()

// 展开(所有)菜单;
tree.expand();

tree.expandNode()

var node = tree.getNode("2");

/**
 * @brief: 展开某个节点
 * @param {} node 节点信息
 * @param {} boolean
 * 		true:子节点跟随父节点一样展开;
 * 		false:子节点不展开;
 * @return {*}
 */
tree.expandNode(node, boolean);

tree.getSelected()

/**
* @brief: 获取选中节点
* @return {nodes} 节点集合
*/
const nodes = tree.getSelected();

tree.getNode(id)

/**
 * @brief: 获取某个特定节点
 * @param {string} id 节点的id
 * @return {*}
 */
tree1.getNode(id);
// demo
var node = tree.getNode("2");

tree.getNodes()

/**
 * @brief: 获取所有节点
 * @return {*} 返回一个所有节点的集合
 */
const result5 = tree.getNodes()

注意:这里源码不对,修改了一下;

const obj = {
  getNodes: function () {
    var a = this,
      arr = [], // !这里缺少空 arr 定义,下面调用 push 会报错
      oi = new i((v = v || {})),
      nt = tt[v.selector]

    for (var key in nt.mapping) {
      var treeNode = nt.mapping[key]
      if (treeNode && treeNode.item && treeNode.id != 'root') {
        arr.push(treeNode.item)
      }
    }
    return arr
  },
}

tree.getSelected()

// 销毁 treetable
tree.getSelected();

tree.checkNode()

var node = tree.getNode("1");

/**
 * @brief: 勾选或取消勾选节点
 * @param {} node 节点信息
 * @param {} boolean
 * 		true:勾选;
 * 		false:取消勾选;
 * @return {*}
 */
tree.checkNode(node, boolean)

tree.setChkDisabled()

var node = tree.getNode("1");

/**
 * @brief: 禁用或解禁 某个节点的 checkbox复选
 * @param {} node 节点信息
 * @param {} boolean
 * 		true:禁用;
 * 		false:解禁;
 * @return {*}
 */
tree.setChkDisabled(node, boolean)

注意:该 api 调用不是很明显,可点击 “全部复选”进行验证。

tree.checkAllNodes()

/**
 * @brief:
 * @param {boolean} boolean
 *    true 全选
 *    false 取消全选
 * @return {*}
 */
tree.checkAllNodes(boolean);

tree.getNodeByParam()

/**
 * @brief: 根据节点数据的属性搜索
 * @param {} key 需要精确匹配的属性名称
 * @param {} value:需要精确匹配的属性值
 * @param {} [parentNode]: (可选)可以指定在某个父节点下的子节点中搜索,忽略此参数,表示在全部节点中搜索
 * @return {json} node 
 * 		null 没有结果返回null;
 * 		获取条件完全匹配的节点数据 JSON 对象集合
 */
// var node = tree.getNodeByParam(key, value, parentNode);

// 例如:
var node = tree.getNodeByParam("name", "子节点21", tree.getNode("1"));

编辑功能

添加节点

【核心】添加节点 api。

tree.addNode(targetNode, node)

【添加1】添加根节点

/*
tree.addNode() api 添加节点;
添加根节点时,第1参数为 null;
第2参数是一个节点对象,children 字段是一级节点。
*/
const node = {
  id: '4',
  name: '父节点4',
  children: [
    {
      id: '41',
      name: '子节点41',
      children: [
        {
          id: '411',
          name: '子节点411',
          children: [
            {
              id: '4111',
              name: '子节点4111',
            },
          ],
        },
      ],
    },
    {
      id: '42',
      name: '子节点42',
      children: [
        {
          id: '421',
          name: '子节点421',
          children: [
            {
              id: '4211',
              name: '子节点4211',
            },
          ],
        },
      ],
    },
  ],
}

tree.addNode(null, node);

【添加2】某个节点下添加子节点

/*
类似上面;
只是第1参数,变成了某个节点对象
*/
const node = {
  id: '22',
  name: '子节点22',
  children: [
    {
      id: '221',
      name: '子节点221',
      children: [
        {
          id: '2211',
          name: '子节点2211',
          children: [
            {
              id: '22111',
              name: '子节点22111',
            },
          ],
        },
      ],
    },
    {
      id: '222',
      name: '子节点222',
      children: [
        {
          id: '2221',
          name: '子节点2221',
          children: [
            {
              id: '22211',
              name: '子节点22211',
            },
          ],
        },
      ],
    },
  ],
}

tree.addNode(tree.getNode("2"), node);

编辑节点

var node = tree.getNode("3");
node.name = '我就是变个名字';

tree.editNodeName(node);

删除节点

var node = tree.getNode("2");
tree.removeNode(node);
// tip: 会连同所有子节点一起删除

3.1、treetable-lay

github 仓库

【简介】在 layui 数据表格之上进行扩展实现。

3.2、使用

1、下载包的整个文件夹,放在项目里;
2、使用模块加载的方式使用;

layui.config({
    base: 'module/'
}).extend({
    treetable: 'treetable-lay/treetable'
}).use(['treetable'], function () {
    var treetable = layui.treetable;
    
});

3、渲染表格;

<table id="table1" class="layui-table" lay-filter="table1"></table>

<script>
layui.use(['treetable'], function () {
    var treetable = layui.treetable;
    
    // 渲染表格
    treetable.render({
        treeColIndex: 2,          // treetable新增参数
        treeSpid: -1,             // treetable新增参数
        treeIdName: 'd_id',       // treetable新增参数
        treePidName: 'd_pid',     // treetable新增参数
        treeDefaultClose: true,   // treetable新增参数
        treeLinkage: true,        // treetable新增参数
        elem: '#table1',
        url: 'json/data1.json',
        cols: [[
            {type: 'numbers'},
            {field: 'id', title: 'id'},
            {field: 'name', title: 'name'},
            {field: 'sex', title: 'sex'},
            {field: 'pid', title: 'pid'},
        ]]
    });
});
</script>

4、修改下样式表追加位置:

// treetable.js 内搜索 xxx.css
layui.link(layui.cache.base + '/treetable-lay/treetable.css');

【示例】treetable-lay 渲染一个树表

3.3、说明

【注意】
1、可以使用 url 传递数据,也可以使用 data 传递数据,如果使用 url 传递数据,参数是 where 字段。
(和 layui table 组件的使用方式一致。)
2、其他注意实现写在下面。

【数据格式!!】
总而言之就是以id、pid的形式,不是以subMenus的形式,当然id、pid这两个字段的名称可以自定义:
示例返回:

{
  "code": 0,
  "msg": "ok",
  "data": [{
      "id": 1,
      "name": "xx",
      "sex": "male",
      "pid": -1
    },{
      "id": 2,
      "name": "xx",
      "sex": "male",
      "pid": 1
    }
  ]
}

3.4、参数说明

【说明】layui table 组件的所有参数都可以用,除此之外 treetable 新增的参数有:
table 组件

treeColIndex

【键】树形图标(箭头、文件夹、文件图标)显示在第几列。
【键值】{int} 0, 1, 2, 3 …
【注意】
1、是必填项;
2、正整数值从0开始计数;(table cols 数组下标)
3、若有序列号或复选列,也计算在数量内;

【示例】树表图标设置在其它列

treeSpid

【键】设置最上级的父级id。
!必填项
【键值】{object}

【例如】这个渲染中
设置的是 treeSpid: -1,
data 渲染数据中,id: 1 和 id: 5 的节点被渲染成一级节点;
在这里插入图片描述

treetable 是以 id 和 pid 字段来渲染树形结构的,如果你的数据没有 id 和 pid 字段,你可以指定 id 和 pid 字段的名称(用下面2个参数)。

treeIdName

【键】id 在你的数据字段中的名称。。
【键值】{string}
【示例】自定义 treetable 渲染中 id 在数据中的字段

treePidName

【键】pid 在你的数据字段中的名称。。
【键值】{string}
【示例】自定义 treetable 渲染中 pid 在数据中的字段

treeDefaultClose

【键】是否默认折叠
【键值】{boolean}
false (默认)是全部展开的
true 设置表格初始都折叠。
【示例】对比其它是示例,这里渲染表格时,默认展开树表

treeLinkage

【键】父级展开时是否自动展开所有子级。
【键值】{boolean}
false (默认)父级展开不展开子集。
true 父级展开,同时展开子集。
【示例】父级展开时,自动展开子集

注意!!!

1、不能使用分页功能,即使写了 page: true,也会忽略该参数;(所以这个参数默认是 false)
2、不能使用排序功能,不要开启排序功能;
3、!!table.reload() 不能实现刷新,请参考 demo 的刷新;
4、除了文档上写的 treetable.xxx 的方法之外,其他数据表格的方法都使用 table.xxx;
5、建议删除和修改操作 请求完后台之后,刷新(重新渲染)表格,最好不要使用 obj.delete 方式删除。

3.5、静态方法

treetable.expandAll()

/**
* @brief: 展开所有节点
* @param {strign} selector 树表渲染到的 table 元素的 id 选择器
* @return {*}
*/
// treetable.expandAll(selector)

// demo
treetable.expandAll('#table1')

【示例】手动全部展开

treetable.foldAll()

/**
* @brief: 折叠所有节点
* @param {strign} selector 树表渲染到的 table 元素的 id 选择器
* @return {*}
*/
// treetable.foldAll(selector)

// demo
treetable.foldAll('#table1')

【示例】手动全部展开

3.6、自定义树表图标

【定义位置】
若项目中统一 一种风格的图标,则在 treetable.css 中修改。
若是单独的,则定义一个样式表,单独引入。

【定义方式】
(1)使用 layui 组件的图标;
(2)使用 iconfont 自定义的图标;

【使用 layui 组件的图标】
渲染效果
统一项目图标风格 + 使用 layui 自己的图标

【使用 iconfont 自定义的图标】和上面修改类似
1、先将自定义图标上传到 iconfont;
2、下载到项目,link 标签引入;

<link rel="stylesheet" href="/layui/treetable-lay/iconfont/iconfont.css" />

3、追加自定义样式表,因为默认的 treetable.css 是js 追加的,若不追加 css,会被这里的覆盖;(或者将 js 追加 treetable.css 改为 link 引入)

layui.link(location.origin + '/layui/treetable-lay/style2.css')

4、自定义图标的内容

【示例】iconfont 自定义图标

3.6、重载树表

【注意】虽然上面说了除树表自己的 配置项和api 都用 table 组件的,单这里重载不能调用 table.reload() api。
【实现】重新调用 .render() api。

var renderTable = function() {
	treetable.render({
		// ...
	})
}

// 事件监听中重新调用此方法

【示例】重载表格

【拓展】增强用户体验 —— load 加载提示

<button class="btn1">重载树表</button>
<hr />
<table id="table1" class="layui-table" lay-filter="table1"></table>
function treetableRender() {
  layer.load(2)
  treetable.render({
    ...defaultConfig,
    ...{
      done: function () {
        layer.closeAll('loading')
      },
    },
  })
}
treetableRender() // 默认渲染

$('.btn1').on('click', function () {
  treetableRender()
})

3.7、监听工具条

【语法】同 table 组件。

// 1、cols 中设置表头
// { templet: '#oper-col', title: 'oper' },

// 2、设置解析的工具栏模板;
<!-- 操作列 -->
<script type="text/html" id="oper-col">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>

// 3、监听工具条 (依赖 table 模块)
table.on('tool(table1)', function (obj) {
    var data = obj.data;
    var layEvent = obj.event;

    if (layEvent === 'del') {
        layer.msg('删除' + data.id);
    } else if (layEvent === 'edit') {
        layer.msg('修改' + data.id);
    }
});

【示例】树表工具栏监听

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值