layui-动态表格使用心得
做项目过程中,使用了layui库的动态表格。在此记录特别的使用方式。
1、异步数据返回后,通过layui渲染表格
不使用layui的异步获取功能url,自己调接口获取数据,可以对数据做判断和加工,然后再显示到页面上。
// 初始化表格-带分页 const load = function (data){ layui.use(['table','laypage'], function() { const table = layui.table; const laypage = layui.laypage; // 根据页面高度定义表格高度 const fixHeight = Math.floor((window.innerHeight - 310) * 0.95); table.render({ elem: '#lay-table', height: fixHeight, data: data.list, // 通过接口获取的数据 cols: [[ // 设置对应字段,宽度,位置,自定义显示 {field: 'areaShortName', title: '省区', width: 80}, {field: '', title: '项目整体偏差', align: 'right', minWidth: 90, templet: function(d){ return `<div class="cell-box"><div class="cell-box-top">${d.projectDeviationRate}%</div><div>${d.projectDeviationDays}天</div></div>` } } ]], text: { none: `<div class="lay-none-data"><span>暂无数据</span><img src="images/pm/usersystem/index/figure-none.svg"></div>` //无数据提示,默认:无数据。注:该属性为 layui 2.2.5 开始新增 }, limit: viewModel.pageSize, // 分页设置,不设置有问题 }); // 分页设置 laypage.render({ elem: 'lay-page', //注意,这里的 test1 是 ID,不用加 # 号 count: data.totalRecord, //数据总数,从服务端得到 limit: viewModel.pageSize, limits: [10, 20, 50, 100], curr: viewModel.draw, layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'], jump: function(obj, first){ //首次不执行 if(!first){ viewModel.draw = obj.curr; //得到当前页,以便向服务端请求对应页的数据。 viewModel.pageSize = obj.limit; //得到每页显示的条数 loadData(); } } }); }) }
2、表头点击事件
表头设置点击事件,通过点击,切换表头显示,并切换当前列数据。
// 自定义表头显示 viewModel.getCheckoutMoney = function (){ let checkoutMoney = ''; if(viewModel.checkFlag === 'original'){ checkoutMoney = '<div class="layui-title-currency"></div>'; }else { checkoutMoney = '<div class="layui-title-currency"></div>'; } return checkoutMoney; } // 由于全局定义事件,所以要清除上一次绑定的事件 $(document).off('click', '.layui-title-currency'); // 定义表头切换事件-全局定义事件,把事件定义到表头的元素(.layui-title-currency)上 $(document).on("click",".layui-title-currency",function(event){ event.stopPropagation(); if(viewModel.checkFlag === 'original'){ viewModel.checkFlag = 'domestic'; }else{ viewModel.checkFlag = 'original'; } })
// table配置列cols {field: '', title: viewModel.getCheckoutMoney(), minWidth: 110, templet: function (d){ if(viewModel.checkFlag === 'original'){ return `<div class="layui-body-currency"></div>` }else{ return `<div class="layui-body-currency"></div>` } } },
3、排序-后台排序
配置table的排序,使用后台排序好的数据。初始化数据时用render配置,切换排序时,重载表格,否则表头重新刷新,排序箭头会复原。
// 初始化配置 table.render({ elem: '#lay-table', height: fixHeight, data: data, // 排序按钮显示 cols: {field: `projectYear0`,title: `2019年`, minWidth: 85, align: 'right', sort: true, templet: function(d){ return `<div class="cell-box"></div>` } }, autoSort: false, //禁用前端自动排序。注意:该参数为 layui 2.4.4 新增 initSort: { field: 'projectYear0', //排序字段,对应 cols 设定的各字段名 type: 'desc' //排序方式 asc: 升序、desc: 降序、null: 默认排序 } }) //监听排序事件 table.on('sort(lay-table-filter)', function(obj){ //注:sort 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值" //obj.field 当前排序的字段名 //obj.type 当前排序类型:desc(降序)、asc(升序)、null(空对象,默认排序) table.reload('lay-table', { initSort: obj, //设置默认排序后需要配置,否则一直保持默认排序按钮 }); if(obj.type){ sortData(obj.field, obj.type); } }); // 排序获取数据 const sortData = function (order, direction){ ...... reload(data) // 排序切换数据的时候,保留表头箭头朝向,使用表格重载 } // 表格重载 const reload = function (data){ layui.use(['table'], function() { const table = layui.table; table.reload('lay-table', { data: data }); }) }
4、合并行并且固定列
不合并行的表格,设置固定列没问题;合并行的表格,设置右侧固定列会导致表格位置错乱。解决方法如下:
table.render({ elem: '#lay-table', // 页面渲染完后回调函数-做一些操作 done: function (res, curr, count) { //解决fixed固定,而导致的th高度不一致 $(".layui-table-fixed-l .layui-table-header tr").each(function (index, val){ $(this).find('th').each(function (childIndex){ const tr = $($(".layui-table-header").find('tr'))[index]; const td = $($(tr).find('th'))[childIndex]; $(this).height($(td).height()); }) }) $(".layui-table-fixed-l .layui-table-header thead tr").each(function (index) { $(this).height($($(".layui-table-header tr")[index]).height()); }); } }
5、列显示隐藏
表头动态显示,通过下拉框选择哪些列显示。layui有一个隐藏列的属性sort,但是这个属性没有操作方法;经过各种尝试,最终的方案是:
- 无合并列情况下,使用变量定义sort属性值,通过改变变量改变sort显示。
- 如果是合并列下,每次切换后重新构建列配置cols(合并列并且右固定的情况下,改变sort属性值会表格错乱,暂无找到原因)。
6、checkbox使用
表格里使用checkbox多选。初始化表格清空checkbox框。
layui.use(['table','laypage','form'], function() { const table = layui.table; const laypage = layui.laypage; const form = layui.form; cols: [[ //配置checkbox框 {type: 'checkbox', LAY_CHECKED: false, hide: viewModel.data.hideReview()}, ]], done: function (res, curr, count) { //初始化清除checkbox选中 $("input[type='checkbox'][name='layTableCheckbox']").prop('checked', false); form.render("checkbox"); }, //checkbox框选中触发回调事件 table.on('checkbox(lay-table-filter)', function(obj){ //如果触发的是全选,obj.type则为:all,如果触发的是单选,则为:one }) })
遇到的问题:
1、在vue里使用时,col里使用 templet 时,直接写@click方法无效,如:
{field: 'code', title: '编码', templet: function (d){ return '<div @click="look()">{{d.code}}</div>' } }
至于原因,可能跟vue的生命周期有关。经过尝试,使用toolbar是可以的,如:
<script type="text/html" id="lookHandle"> <!-- 这里同样支持 laytpl 语法,如: --> <span class="fixed-active" lay-event="look">{{d.code}}</span> </script> {field: 'code', title: '方法论编码', toolbar: '#lookHandle'} // 监听工具条点击事件 table.on('tool(lay-table-filter)', function(obj) { const data = obj.data; //获得当前行数据 const layEvent = obj.event; //获得 lay-event 对应的值 if(layEvent === 'look'){ //查看 app.lookMethodology(data.pkSmMethodology,'look'); } })