比较简单请耐心查看
效果图
实现方式
首先引入组件(代码放到最后面了)
layui.config({
base: $projectPath+"/js/util/layui-module/"
}).extend({
treeSelect: "treeSelect",
treeTable: "treeTable",
});
js 中
var layer;
var form;
var table;
var treeTable;
var interUrl = {
select: $projectPath+'/sys/menu/selecTreeTable',
}
layui.use([ 'layer', 'form', 'table', "treeTable"], function() {
layer = layui.layer;
form = layui.form;
table = layui.table;
treeTable = layui.treeTable;
// 执行一个 table 实例
var treeTablParam = treeTable.render({
elem : '#data_table',
id : 'data_table',
url : interUrl.select,
height:'full-120',
page: false,
toolbar : '#toolberLeft',
treeColIndex: 1,// 树形图标显示在第几列
treeSpid: 0,// 最上级的父级id
treeIdName: 'mid',// id字段的名称
treePidName: 'parentId',// pid字段的名称
treeDefaultClose: false,// 是否默认折叠
treelinkage: true,// 父级展开时是否自动展开所有子级
cols : [[ // 表头
{type : 'checkbox', fixed : 'left', hide: true},
{field : 'mname', title : '菜单名称', align : 'center', width: '150'},
{field : 'mid', title : 'ID', fixed : 'left', align : 'center', width: '80', hide: true},
{field : 'code', title : '编码', align : 'center', width: '100',},
{field : 'isProject', title : '权限', align : 'center', width: '100', templet: (d) => getDictText("is_project",d.isProject)},
{field : 'url', title : '跳转路径', align : 'center', width: '300'},
{field : 'iconCls', title : '图标样式', align : 'center', width: '150',
templet:function(res){
return ''+res.iconCls+'';
}
},{title : '操作', align : 'center', width: '300', toolbar : '#toolRow'}
// fixed : 'right',
]]
});
// 头部左侧事件
table.on('toolbar(data_table)', function(obj) {
if (obj.event === 'search') {
var name = $("#serarch_name").val();
treeTablParam.where = {"mname": name};
treeTablParam = treeTable.render(treeTablParam);
setTimeout(function(){
$("#serarch_name").val(name);
},500)
}else if(obj.event === 'add'){
}else if(obj.event === 'expand'){
treeTable.expandAll('#data_table');
}else if(obj.event === 'fold'){
treeTable.foldAll('#data_table');
}
})
// 监听行工具事件
table.on('tool(data_table)', function(obj) {
var data = obj.data;
if (obj.event === 'add') {
}else if (obj.event === 'del') {
} else if (obj.event === 'edit') {
}else if (obj.event === 'detail') {
}
});
})
html 中
java 中(serviceImpl层)
public Result> selecTreeTable(MenuEntity m) {
List list = dao.selectTreeAll();
if(StrUtil.isNotBlank(m.getMname())) {
List resList = new ArrayList();
for(MenuEntityResp menu : list) {
if(menu.getMname().indexOf(m.getMname()) != -1) {
resList.add(menu);
for(MenuEntityResp menuTwo : list) {
if(menuTwo.getParentId().equals(menu.getMid())) {
resList.add(menuTwo);
}
}
}
}
return Result.success(resList, (long)resList.size());
}// 这里的Result是分页的数据和总数,我这里直接查询所有并没有分页
return Result.success(list, (long)list.size());
}
treetable.css和treeTable.js代码(组件源码)
treetable.css
.treeTable-empty {
width: 20px;
display: inline-block;
}
.treeTable-icon {
cursor: pointer;
}
.treeTable-icon .layui-icon-triangle-d:before {
content: "e623";
}
.treeTable-icon.open .layui-icon-triangle-d:before {
content: "e625";
background-color: transparent;
}
treeTable.js
layui.define(['layer', 'table'], function (exports) {
var $ = layui.jquery;
var layer = layui.layer;
var table = layui.table;
var treetable = {
// 渲染树形表格
render: function (param) {
// 检查参数
if (!treetable.checkParam(param)) {
return;
}
// 复制一个新对象
var newParam = $.extend(true,{},param) ;
// 获取数据
if (!param.where && param.data) {
treetable.init(param, param.data);
} else {
$.getJSON(param.url, param.where, function (res) {
treetable.init(param, res.data);
});
}
return newParam;
},
// 渲染表格
init: function (param, data) {
var mData = [];
var doneCallback = param.done;
var tNodes = data;
// 补上id和pid字段
for (var i = 0; i < tNodes.length; i++) {
var tt = tNodes[i];
if (!tt.id) {
if (!param.treeIdName) {
layer.msg('参数treeIdName不能为空', {icon: 5});
return;
}
tt.id = tt[param.treeIdName];
}
if (!tt.pid) {
if (!param.treePidName) {
layer.msg('参数treePidName不能为空', {icon: 5});
return;
}
tt.pid = tt[param.treePidName];
}
}
// 对数据进行排序
var sort = function (s_pid, data) {
for (var i = 0; i < data.length; i++) {
if (data[i].pid == s_pid) {
var len = mData.length;
if (len > 0 && mData[len - 1].id == s_pid) {
mData[len - 1].isParent = true;
}
mData.push(data[i]);
sort(data[i].id, data);
}
}
};
sort(param.treeSpid, tNodes);
if(mData.length < 1){
mData = tNodes;
}
// 重写参数
param.url = undefined;
param.data = mData;
param.page = {
count: param.data.length,
limit: param.data.length
};
param.cols[0][param.treeColIndex].templet = function (d) {
var mId = d.id;
var mPid = d.pid;
var isDir = d.isParent;
var emptyNum = treetable.getEmptyNum(mPid, mData);
var iconHtml = '';
for (var i = 0; i < emptyNum; i++) {
iconHtml += '';
}
if (isDir) {
iconHtml += ' ';
} else {
iconHtml += '';
}
iconHtml += ' ';
var ttype = isDir ? 'dir' : 'file';
var vg = '';
return vg + iconHtml + d[param.cols[0][param.treeColIndex].field] + ''
};
param.done = function (res, curr, count) {
$(param.elem).next().addClass('treeTable');
$('.treeTable .layui-table-page').css('display', 'none');
$(param.elem).next().attr('treelinkage', param.treelinkage);
// 绑定事件换成对body绑定
if (param.treeDefaultClose) {
treetable.foldAll(param.elem);
}
if (doneCallback) {
doneCallback(res, curr, count);
}
};
// 渲染表格
table.render(param);
},
// 计算缩进的数量
getEmptyNum: function (pid, data) {
var num = 0;
if (!pid) {
return num;
}
var tPid;
for (var i = 0; i < data.length; i++) {
if (pid == data[i].id) {
num += 1;
tPid = data[i].pid;
break;
}
}
return num + treetable.getEmptyNum(tPid, data);
},
// 展开/折叠行
toggleRows: function ($dom, linkage) {
var type = $dom.attr('lay-ttype');
if ('file' == type) {
return;
}
var mId = $dom.attr('lay-tid');
var isOpen = $dom.hasClass('open');
if (isOpen) {
$dom.removeClass('open');
} else {
$dom.addClass('open');
}
$dom.closest('tbody').find('tr').each(function () {
var $ti = $(this).find('.treeTable-icon');
var pid = $ti.attr('lay-tpid');
var ttype = $ti.attr('lay-ttype');
var tOpen = $ti.hasClass('open');
if (mId == pid) {
if (isOpen) {
$(this).hide();
if ('dir' == ttype && tOpen == isOpen) {
$ti.trigger('click');
}
} else {
$(this).show();
if (linkage && 'dir' == ttype && tOpen == isOpen) {
$ti.trigger('click');
}
}
}
});
},
// 检查参数
checkParam: function (param) {
if (!param.treeSpid && param.treeSpid != 0) {
layer.msg('参数treeSpid不能为空', {icon: 5});
return false;
}
if (!param.treeColIndex && param.treeColIndex != 0) {
layer.msg('参数treeColIndex不能为空', {icon: 5});
return false;
}
return true;
},
// 展开所有
expandAll: function (dom) {
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
var $ti = $(this).find('.treeTable-icon');
var ttype = $ti.attr('lay-ttype');
var tOpen = $ti.hasClass('open');
if ('dir' == ttype && !tOpen) {
$ti.trigger('click');
}
});
},
// 折叠所有
foldAll: function (dom) {
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () {
var $ti = $(this).find('.treeTable-icon');
var ttype = $ti.attr('lay-ttype');
var tOpen = $ti.hasClass('open');
if ('dir' == ttype && tOpen) {
$ti.trigger('click');
}
});
}
};
// 引入图标
layui.link(layui.cache.base + '/treetable.css');
// 给图标列绑定事件
$('body').on('click', '.treeTable .treeTable-icon', function () {
var treelinkage = $(this).parents('.treeTable').attr('treelinkage');
if ('true' == treelinkage) {
treetable.toggleRows($(this), true);
} else {
treetable.toggleRows($(this), false);
}
});
exports('treeTable', treetable);
});



