Layui踩坑

Layui踩坑

前言

layui一个十分出色的js原生开发框架,性能还是十分ok的,不过对于经常进行vue,react等等开发的小伙伴来说还是有点不适应的。

layui表单限制输入正整数

<div class="layui-form-item">
    <label class="layui-form-label tl" style="width: 160px;">费用:</label>
    <div class="layui-inline">
      <input type="text" name="upload_price" style="width: 240px" value="{{$upload_price ?? ''}}" onKeyUp="this.value=this.value.replace(/[^\.\d]/g,'');" required  lay-verify="required|number" autocomplete="off" class="layui-input">
    </div>
    <div class="layui-inline">人民币</div>
  </div>

主要onKeyUp中的正则的添加

layui实现自定导出excel

layui表格自带导出工具,但是这个工具是导出当前页所有的数据。如果我们要实现多行选中导出如何实现呢?

引入layui提供的excel扩展插件

现有Excel操作前端库中,XLSX.JS功能强大但是操作颇为不便,于是封装了此插件,依赖jQuery,支持Layui插件形式加载,导出仅需一句话。 导出excel功能基于 XLSX.js,下载功能基于 FileSaver,读取文件基于 H5的 FileReader

下载地址将插件下载至本地项目

随后我们在需要用到的页面中通过js引入

<script type="text/html" src="js/layui_exts/excel.js"></script>

引入文件后我们打印layui

可以看到我们的excel插件其实是已经引进来了,接下来我们就可以放心去使用啦。

使用

  1. 布局的话我们就是用table.render({})去渲染就可以,不过记得把checkbox多选给加上。
  2. 拿到我们所有选中的需要导出的数据
var selectData = layui.table.checkStatus('tableEle').data;
// tableEle为我们的表格标签的id
  1. 设置过滤字段,因为这个插件导出的是所有后端返回的表格数据,有时候我们展示或者导出的只是部分页面中展示的数据。因此我们需要将需要导出的字段过滤出来。只导出我们需要导出的数据:
selectData = layui.excel.filterExportData(selectData, [
  'function_attribute'
  ,'uid'
  ,'name'
  ,'sex'
  ,'disabled_start'
  ,'disabled_end'
  ,'explain'
  ,'operator_name'
  ,'operator_at'
]);

以上字段为我们导出excel所需要的数据

  1. 为excel添加表头,如果不进行此操作,导出的excel数据是没有表头信息的。
selectData.unshift({
  function_attribute: '功能属性',
  uid: '被禁用机构/用户uid',
  name: '被禁用机构用户名称',
  sex: '被禁用时长',
  disabled_start: '开始禁用时间',
  disabled_end: '结束禁用时间',
  explain: '被禁用原因',
  operator_name: '操作人',
  operator_at: '操作时间'
});
  1. 调用导出
//调用导出excel
layui.excel.exportExcel({
  sheet1: selectData
}, '被禁用功能管理.xlsx', 'xlsx');

导出的完整代码

<table class="layui-hide" id="test" lay-filter="test"></table>
<script language="JavaScript" src="/js/layui_exts/excel.js"></script>
<script type="text/html" id="toolbarDemo">
  <div class="layui-btn-container">
    <button class="layui-btn layui-btn-sm" lay-event="handleExport">导出</button>
  </div>
</script>
// 表格导出
  function exportExcel() {
    //获取复选框选中的数据
    var selectData = layui.table.checkStatus('test').data;
    selectData = layui.excel.filterExportData(selectData, [
      'function_attribute'
      ,'uid'
      ,'name'
      ,'sex'
      ,'disabled_start'
      ,'disabled_end'
      ,'explain'
      ,'operator_name'
      ,'operator_at'
    ]);
    //添加excel的表头
    selectData.unshift({
      function_attribute: '功能属性',
      uid: '被禁用机构/用户uid',
      name: '被禁用机构用户名称',
      sex: '被禁用时长',
      disabled_start: '开始禁用时间',
      disabled_end: '结束禁用时间',
      explain: '被禁用原因',
      operator_name: '操作人',
      operator_at: '操作时间'
    });
    //调用导出excel
    layui.excel.exportExcel({
      sheet1: selectData
    }, 'xxx.xlsx', 'xlsx');
  }
// 导出
function handleExport() {
	layer.confirm('确定执行导出操作吗?',{btnAlign: 'c',icon: 3, title:'提示'}, function(index){
        exportExcel();
    	layer.close();
	});
}

layui弹框中打开表单

情景:设置一段dom表单然后隐藏起来,随后通过layer.open打开弹框后,弹框中的表单校验失效!

原因:我们打开表单时,我们不是引入$(‘#dom’).html()而是需要引入$(‘#dom’)这样才可以

<!-- 弹框 订单确认 -->
<form class="layui-form" style="display: none" id="order_confirm" action="">
	<div class="layui-form-item">
		<div class="layui-inline-block df-ac">
			<label class="layui-form-label label" for="orderid">操作人:</label>
			<div class="layui-input-inline order_confirm-operation-name">
				爱妃的鱼儿当前登录用户
				<input type="hidden" class="layui-input" name="operation_name" value="爱妃的鱼儿">
			</div>
		</div>
	</div>
	<div class="layui-form-item">
		<div class="layui-inline-block">
			<label class="layui-form-label label" for="orderid">收货人:</label>
			<div class="layui-input-inline">
				<input type="text" name="receive_name" required lay-verify="require" autocomplete="off" class="layui-input">
			</div>
		</div>
	</div>
	<div class="layui-form-item">
		<div class="layui-inline-block">
			<label class="layui-form-label label" for="orderid">收货地址:</label>
			<div class="layui-input-inline">
				<input type="text" name="receive_address" required lay-verify="require" autocomplete="off" class="layui-input">
			</div>
		</div>
	</div>
	<div class="layui-form-item">
		<div class="layui-inline-block">
			<label class="layui-form-label label" for="orderid">收货人联系方式:</label>
			<div class="layui-input-inline">
				<input type="text" name="receive_phone" required lay-verify="require" autocomplete="off" class="layui-input">
			</div>
		</div>
	</div>
	<div class="layui-form-item">
		<div class="layui-inline-block">
			<label class="layui-form-label label" for="orderid"></label>
		 	<button class="layui-btn layui-layer-btn0" lay-submit lay-filter="submitOrderConfirm">确定订单</button>
		</div>
	</div>
</form>

layer.open({
	title: '确认订单',
	type: 1,
	area: ['500px', '360px'],
	content: $("#order_confirm")
})

Layui表格固定列行高不一致的问题

layui表格行高不统一

此问题的出现多半是由于某一列中的高度超出了表格默认的高度,导致其他列高度变化,但固定列高度不变,就出现了现在的问题。

解决方案:

  table.init('parse-table', { //转化静态表格
      cellMinWidth : 100,
      cellMinHeight: 80,
done: function(res,curr,count) {
	$(".layui-table-main  tr").each(function (index ,val) {
		$($(".layui-table-fixed .layui-table-body tbody tr")[index]).height($(val).height());
	});
}
  });

在表格render的回调中对固定列的高度重新计算即可!

Layui弹框关闭并刷新页面

场景:打开弹框,表单提交成功后,关闭弹框,并刷新列表

$.ajax({
          type: "POST",
          url: 'xxx',
          data: {
              id: '111'
          },
          dataType: "json",
          success: function(res){
            if(res.status != 1){
              layui.layer.msg(res.msg, {icon: 5, anim: 6, time: 1000});
              return false;
            }
            layer.msg(res.msg, {icon: 1,time: 1000},function() {
              window.parent.layer.closeAll();
              window.parent.location.reload();
            });
          }
        });

Layui表单关闭默认提交和刷新

在表单提交后,表单会有默认刷新,有时候,我们需要调用ajax来进行表单提交操作。这时我们需要屏蔽表单原本的action提交

<form class="layui-form" onsubmit="return false;">
</form>

只需要给表单添加 onsubmit=”return false;”即可

Layui文件上传失败后对失败文件的缓存

使用Layui的upload插件进行上传的时候,有这样一个问题,如果文件上传失败后,它会将上一次失败的文件进行缓存,在下一次进行上传操作的时候,会将上一次失败的文件在进行一次上传尝试

所以造成的问题就是:如果上传失败的图片因为后端接口报错,那么我们上传失败一次后,后续上传其他的正常的图片也都会报错。其实除了第一次失败的图片外其他图片都成功了。

这样的原因就是:对第一次上传失败的文件进行了缓存,后续的每次上传都会带着上传上去。所以上传一次报错一次。

解决方案:

var files;
function clearImgUploadCach() {
    for (let v in files) {
        delete files[v]; // 删除上传文件的缓存
    }
}
upload.render({
    elem: '#upload',
    multiple: true,
    url: DOMAIN + '/upload',
    data: {
        channel: 'common'
    },
    size: "2048",
    exts: 'jpg|png|jpeg',
    before: function(obj) {
        files = obj.pushFile(); // 记录上传的文件
    },
    error: function(err,index) {
        clearImgUploadCach('');
    }
});

重点是上传前对上传文件做一次变量的存储,然后再失败后记录的文件做一次缓存的清除。

Layui调起弹框后回车重复调起弹框

​ 使用Layui.open调起弹框后,按键盘回车,会重复出现多个弹框,背景色逐渐加深的情况。修复:

layer.open({
	type: 2,
	title: '信息',
	url: 'xxxx',
	success: function() {
		$(':focus').blur();
	}
})

对:focus做一次失焦

Layui表格中嵌入select选择器

layui表格嵌入select.png
正常html末班书写,直接吸入对应的select就ok,没有任何问题。但是如果我们通过js去渲染呢?

  1. 我们需要提高表格中选择器的层级

    /* 防止下拉框下拉值被遮盖*/
        .layui-table-cell {
            overflow: visible;
        }
     
        .layui-table-box {
            overflow: visible;
        }
     
        .layui-table-body {
            overflow: visible;
        }
        /* 调整高度 */
        td .layui-form-select{
            margin-top: -10px;
            margin-left: -15px;
            margin-right: -15px;
        }

    如果不添加的话会出现层级问题,导出选择器下拉部分出不来

    1. 选择器更改时,我们如何监听呢?
    2. 选择器属于表单模块,所以我们再写魔板的时候就需要讲选择器写入form表单中
    {field:'status', title:'审核状态', templet: function (res) {
      if (res.status == 1) {
        return `
        <div class="layui-form">
        <select name="status" data-uid="${res.id}" lay-filter="statusSelect" lay-verify="required">
        <option value="">待审核</option>
        <option value="1">审核通过</option>
        <option value="2">审核驳回</option>
        </select>
        </div>
        `
      } else if (res.status == 2) {
        return '审核通过'
      } else {
        return '审核驳回'
      }
    }}

    监听选择器

    form.on('select(statusSelect)', function(data){
      var _uid = data.elem.attributes["data-uid"].value; // 当前行元素的uid
      if (data.value == 1) {
        layer.confirm('确定对照片进行审核通过操作?',{btnAlign: 'c',icon: 3, title:'提示'}, function(index){
          layer.close(index);
        }, function(){
          window.location.reload();
        });
      } else if (data.value == 2) {
      }
    });

    至此,Layui表单中国的选择器就可以正常展示。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!