layui的使用(table/form)——layui踩坑记录

本文详细介绍了基于layui框架在前后端不分离的MVC模式下,如何实现页面元素如button、input、select、table的使用,包括功能实现、数据交互和操作按钮的动态渲染。重点讲解了表格的渲染、条件检索、操作功能,如刷新、获取input和select值,以及日期选择器和操作按钮的事件监听。同时,文章还展示了动态加载数据、表格操作事件如查看、编辑、删除的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公司之前的老系统是前后端不分离的MVC模式,是基于Layui开发的。

1.引入layui

引入文件的具体路径需要根据实际项目来。

<link href="~/Content/plugins/layui-v2.4.3/layui/css/layui.css" rel="stylesheet" />
<script src="~/Content/plugins/layui-v2.4.3/layui/layui.js"></script>

2. 页面功能分析

在这里插入图片描述
页面结构如上图所示:
可以看到页面中有button input select table等。

button的使用

<button class="layui-btn check" onclick="refresh()">刷新</button>

刷新页面功能实现:

//刷新
function refresh() {
    window.location.reload();
}
input的使用

<input type="text" style="width:300px;margin-right:10px;" name="name" id="name" class="sinput" placeholder="请输入供应商全称" autofocus="" maxlength="50" />
获取input中的内容可以通过$('#name').val()的方式来获取

select的使用
<select name="type" lay-filter="aihao" id="type">
    <option value="">请选择供应商类型</option>
    <option value="1">原厂</option>
    <option value="2">代理</option>
    <option value="4">贸易</option>
</select>

获取select中选择的内容可以通过$('#type').val()的方式来获取
如果是需要通过接口获取select中的选项,然后动态渲染到页面中的话,则需要下面的方式:

layui.use(['form'], function () {
	var form = layui.form;
	//调用接口获取数据
	//$.get(接口地址,函数回调)
	$.get(url + "Brand", function (res) {
        console.log(res);
        if (res.success) {
            var select = $("#brand");//TypeID为HTML标签ID
            $.each(res.data.items, function (index, item) {
                select.append(new Option(item.name, item.id));// 下拉菜单里添加元素  这个地方的参数,第一个是展示文字,第二个是value值
            });
            layui.form.render("select");
        }
    })
})

这个地方花了我好久的时间,因为我开始用的是字符串拼接,模板字符串的方式我也用了,append和html的添加dom元素的方式都不生效,才百度到这个new Option的方式来处理……

日期选择控件

<input type="text" class="sinput" id="time1" placeholder="审核通过开始时间">
使用方式如下:

layui.use(['laydate'], function () {
	var laydate = layui.laydate;
	//执行一个laydate实例
    laydate.render({
        elem: '#time1' //指定元素
    });
})
table的使用——这个内容很多

分别是:表格的渲染,表格操作按钮的添加及判断展示,表格的重载(条件检索),表格操作按钮的触发等;

表格的渲染

html部分代码

<div style="min-height: 500px;" class="list_data_list">
   <table id="demo" lay-filter="test"></table> //表格要渲染的dom元素  id用于渲染表格,lay-filter="test"用于触发事件
   <script type="text/html" id="toolbarDemo"> //表格的操作按钮
       <div class="layui-btn-container"> //lay-event="update" 这种方式可以在监听表格操作按钮触发事件时能够监听到,ley-event的值可以自定义
           <button type="button" class="layui-btn layui-btn-sm" lay-event="view">查看</button>
           <button type="button" class="layui-btn layui-btn-sm" style="background:#409EFF" lay-event="update">修改</button>
           {{# if(d.state=='启用'){ }} //根据表格中的数据判断是否展示按钮
           <button type="button" class="layui-btn layui-btn-sm" style="background:red;" id="statusoff" lay-event="off">停用</button>
           {{# } }}
           {{# if(d.state=='禁用'){ }}
           <button type="button" class="layui-btn layui-btn-sm" style="background:green;" id="statuson" lay-event="on">启用</button>
           {{# } }}
           <button type="button" class="layui-btn layui-btn-sm" lay-event="delete">删除</button>
       </div>
   </script>
</div>

js部分的代码:

layui.use(['table', 'layer'], function () {
	var table = layui.table;
	//第一个实例
        table.render({
            elem: '#demo'  //html接口中的table的id
            , height: tableHeight //这个我是动态改变的,例如浏览器clientHeight可视区域高度改变是的表格高度也相应改变,还有点bug
            , url: url + "Supplier" //数据接口
            , parseData: function (res) {  //由于接口返回的数据结构与table中默认的数据接口不太一样,因此通过这个函数进行处理
                if (!res.success) { //这个是容错,如果接口返回给我false,我需要弹窗提示错误信息及展示空数据
                    tableData = [];
                    layer.msg(res.message);
                    return {
                        'code': res.code,
                        'data': [],
                        "count": 0,
                    }
                }
                let data = res.data.items;
                data = getEndText(data, 'type', typemenu); //这个地方是调用了一个封装好的方法,将枚举数字改为文字,
                data = getEndText(data, 'platform', platformmenu);
                data = getEndText(data, 'isTemp', isTempmenu);
                data = getEndText(data, 'source', sourcemenu);
                data = getEndText(data, 'checkState', checkStatemenu);
                data = getEndText(data, 'state', statemenu);
                data = getEndText(data, 'rank', rankmenu);
                data = getEndText(data, 'payType', payTypemenu);
                data = getEndText(data, 'accountPeriod', accountPeriodmenu);
                data = getEndText(data, 'riskLevel', riskLevelmenu);
                data = getEndText(data, 'warehouseType', warehouseTypemenu);
                tableData = data; 
                return { //最终返回的格式如下:
                    'code': res.code,
                    'data': data,
                    "count": res.data.total,
                }
            }
            , page: true //开启分页
            , id: 'demoId' //指定table的id,后续可以通过这个id来进行表格的部分操作
            , loading: true //分页加载时展示加载中的提示
            , cols: [[ //表头
                { type: 'checkbox' }  //这个是最左侧的选择框
                , { field: 'id', title: '序号', width: 60 }
                , { field: 'code', title: '供应商代码', width: 100 }
                , { field: 'name', title: '供应商名称', width: 200 }
                , { field: 'type', title: '供应商类型', width: 100 }
                , { field: 'platform', title: '平台', width: 100 }
                , { field: 'source', title: '来源', width: 100 }
                , { field: 'contactName', title: '联系人姓名', width: 100 }
                , { field: 'contactTele', title: '联系电话', width: 150 }
                , { field: 'contactMobile', title: '联系手机号', width: 150 }
                , { field: 'contactAddress', title: '联系地址', width: 200 }
                , { field: 'isTemp', title: '临时供应商', width: 100 }
                , { field: 'middleman', title: '采购对接人', width: 100 }
                , { field: 'settleInTime', title: '审核通过时间', width: 200 }
                , { field: 'rank', title: '等级', width: 100 }
                , { field: 'state', title: '状态', width: 100,style:'color:red' }
                , { field: '', title: '操作', toolbar: "#toolbarDemo", fixed: 'right', width: 260 } //这个是操作按钮的位置,这个地方的toolbar需要跟html中的操作按钮的id保持一致,才能够将html按钮渲染到表格中
            ]],
            done: function (res) {
                console.log('done', res);
                layer.close(index);
            }
        });
        //触发复选事件   checkbox对应的是复选框  test对应的是table表格中的lay-filter="test"
        table.on('checkbox(test)', function (obj) {
        	//判断obj对象是否为空的方式:获取所有的keys为一个数组,如果数组长度为0,则表示是个空对象
        	// Object.keys(对象) 获取对象的key并返回一个数组
            if (!Object.keys(obj.data).length) {
            // 如果是选中,则checked为true,如果是取消选中,则checked为false,这个可以打印一下obj的数据可以知道
                if (obj.checked) {
                    tableData.forEach(item => {
                        selectObj.push(item.id) //我这边是需要获取到所有选中的对象中的id,并存储到一个数组中
                    })

                } else {
                    selectObj = [];
                }
            }
            filterObj(obj); //如果是选中某项,则需要先判断是否已经包含此项,如果是取消某项,也需要先判断是否含有此项
            console.log(selectObj);//此处的selectObj是个id集合的数组,原谅我不严谨的起名方式……
        });
        function filterObj(obj) {
            var len = selectObj.length;
            if (!obj.checked) {
                if (len) {
                    if (selectObj.indexOf(obj.data.id) != -1) { //判断数组中是否包含某一项,可以通过 arr.indexOf(元素)的方式来判断,如果结果等于-1,则表示没有该项,如果含有该元素,则结果是索引值,根据索引值,将取消选中的元素splice掉
                        selectObj.splice(selectObj.indexOf(obj.data.id), 1);
                    }
                }
            } else {
                if (selectObj.indexOf(obj.data.id) == -1) {
                    selectObj.push(obj.data.id);
                }
            }
            selectObj.forEach((obj, index) => { //遍历数组,如果其中有Undefined,则移除掉
                if (obj == undefined) {
                    selectObj.splice(index, 1);
                }
            })
        }
     //触发操作事件 tool对应的就是操作按钮 test对应的是lay-filter="test"
     table.on('tool(test)', function (obj) {
         var id = obj.data.id; //点击操作按钮,对应的是一行数据,这行数据就是obj.data
         switch (obj.event) { // 这就是  lay-event="off" 集合的所有的操作按钮
             case 'view': //如果lay-event="view"查看功能,通过layer.open打开一个弹窗展示详情
                 layer.open({
                     type: 2, //这块的具体数字可以看文档,我对样式没有太多的要求,先实现功能
                     icon: 1,
                     title: '查看信息', //弹窗提示的标题
                     maxmin: true,
                     area: ['1200px', '80%'],//宽高  如果设置为百分数,则根据浏览器的窗口来改变
                     content: "Edit", //这个地方需要指定一个html页面或者要给链接,我的Edit页面是放在同一个文件路径下,因此直接写文件名即可,不用指定扩展名后缀。
                     closeBtn: 1, //关闭按钮的样式
                     success: function (layero, index) { //如果弹窗成功弹出,则执行下面的代码
                         console.log(layero, index); //如果要给弹窗传递数据,则可以通过
                         var obj = $(layero).find("iframe")[0].contentWindow;  //这个是固定写法
                         var body = layer.getChildFrame('body', index);//这个是固定写法
                         body.find(".query").val('id=' + id + '&state=look');//这个body对应的就是弹层本身,我是在弹层页面有个input组件,class类名为query,可以通过body.find('.query')的方式获取到,通过val进行赋值,赋值内容是自定义的,然后在弹层中,给这个input设置样式为:字体为白色,或者透明色,是不会展示出来的。 
                     },
                 });
                 break;
             case 'delete': //
                 layer.confirm('确定删除此条数据吗?', { icon: 3, title: '提示' }, function (index) {
                     console.log(index);
                     if (index) {
                         $.ajax({
                             type: 'delete',
                             url: url + 'Supplier?id=' + id,
                             success: function (res) {
                                 layer.msg("删除成功");
                                 searchTable();
                             }
                         })
                     }
                     layer.close(index);
                 })
                 break;
             case 'update':
                 layer.open({
                     type: 2,
                     icon: 1,
                     title: '编辑信息',
                     maxmin: true,
                     area: ['1200px', '80%'],//宽高
                     content: "Edit",
                     success: function (layero, index) {
                         console.log(layero, index);
                         var obj = $(layero).find("iframe")[0].contentWindow;
                         var body = layer.getChildFrame('body', index);
                         body.find(".query").val('id=' + id + '&state=edit');
                     }
                 });
                 break;
             case 'off':
                 layer.confirm('确定停用吗?', { icon: 3, title: '提示' }, function (index) {
                     $.ajax({
                         type: "PATCH",
                         url: url + "Supplier/Disable/" + id,
                         contentType: "application/x-www-form-urlencoded",
                         success: function (res) {
                             console.log(res);
                             if (res.success) {
                                 layer.msg('停用成功');
                                 setTimeout(() => {
                                     layer.close();
                                     window.location.reload();
                                 }, 500)
                             } else {
                                 layer.msg(res.message)
                             }
                         }
                     });
                 });
                 break;
             case 'on':
                 layer.confirm('确定启用吗?', { icon: 3, title: '提示' }, function (index) {
                     $.ajax({
                         type: "PATCH",
                         url: url + "Supplier/UnDisable/" + id,
                         contentType: "application/x-www-form-urlencoded",
                         success: function (res) {
                             console.log(res);
                             if (res.success) {
                                 layer.msg('启用成功');
                                 setTimeout(() => {
                                     layer.close();
                                     window.location.reload();
                                 }, 500)
                             } else {
                                 layer.msg(res.message)
                             }
                         }
                     });
                 });
                 break;
         };
     });
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶浩成520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值