下载工作台
jQuery 与 Layui 实战

Layui layer、upload 与常用模块

试读上半部分 · 解锁后可读全文

第 10 章 · Layui layer、upload 与常用模块

本章目标:熟练使用 layer 的消息、确认、页面层与 iframe 弹窗;掌握 upload 图片上传、laydate 日期选择、element Tab;了解 laytpl 模板与 flow 流加载;在 admin-demo 完成弹窗编辑 + 图片上传实战。

学时建议:3.5 小时(含 70 分钟跟练)

前置:ch08 表单、ch09 表格;ch07 layer 已初步接触。


10.1 layer 模块:后台交互中枢

layer 提供遮罩、对话框、iframe 子页,是行业常见 Layui 后台删除确认、SKU 编辑弹窗的统一交互层

10.1.1 layer.msg — 轻提示

layer.msg('保存成功', {
  icon: 1,           // 0叹号 1勾 2叉 3问号 4锁 5哭 6笑
  time: 2000,        // 毫秒,0 不自动关闭
  offset: 't'        // 顶部,不挡表格
});
场景推荐
操作成功/失败msg + icon
长文案time: 0 + 用户点遮罩关闭
连续操作避免叠多层,先 layer.closeAll('dialog')

10.1.2 layer.alert — 告警框

layer.alert('您的店铺资质即将过期,请及时更新', {
  icon: 0,
  title: '系统提醒',
  btn: ['知道了']
}, function (index) {
  layer.close(index);
});

适合必须阅读的单按钮通知;多按钮用 btn: ['确定','取消']

10.1.3 layer.confirm — 确认框

layer.confirm('确定下架该商品?', {
  icon: 3,
  title: '操作确认',
  btn: ['确定', '取消']
}, function (index) {
  doOffShelf(id);
  layer.close(index);
}, function () {
  // 取消回调(可选)
});

行业常见删除确认使用自定义 HTML 内容 + 宽按钮区,提升风险说明可读性(见 ch09 对照)。

10.1.4 layer.open — 页面层与 iframe

type用途
0信息(需 content DOM)
1页面层(div)
2iframe 加载子页(编辑表单首选)
3加载层(loading)
// iframe 编辑商品(与 ch08 product-edit 联动)
layer.open({
  type: 2,
  title: '<i class="layui-icon layui-icon-edit"></i> 编辑商品',
  shadeClose: false,
  shade: 0.3,
  maxmin: true,
  area: ['960px', '720px'],
  content: 'product-edit.html?id=' + productId,
  success: function (layero, index) {
    // 可向子页传参:layero.find('iframe')[0].contentWindow
  },
  end: function () {
    table.reload('productTable');
  }
});
// 纯 DOM 弹窗表单(小型快捷编辑)
layer.open({
  type: 1,
  title: '修改库存',
  area: ['400px', '280px'],
  content: $('#stockFormTpl').html(),
  success: function (layero, index) {
    form.render();
    form.on('submit(stockSave)', function (data) {
      updateStock(data.field);
      layer.close(index);
      return false;
    });
  }
});

注意type:1 内表单事件需在 success 里绑定;重复打开会重复绑定,可用 form.on 唯一 filter 或先 off

10.1.5 layer.load 与关闭

var idx = layer.load(1, { shade: [0.15, '#000'] });
$.ajax({
  complete: function () { layer.close(idx); }
});

表格整页遮罩也可用自定义 #loadingOverlay(行业常见做法),二者择一保持项目统一。


10.2 upload 文件上传

10.2.1 单图上传(商品主图)

<div class="layui-upload">
  <button type="button" class="layui-btn" id="btnUpload">
    <i class="layui-icon layui-icon-upload"></i> 上传主图
  </button>
  <div class="layui-upload-list">
    <img class="layui-upload-img" id="previewImg" style="max-width:200px;">
    <p id="uploadText"></p>
  </div>
</div>
<input type="hidden" name="cover_url" id="coverUrl">
layui.use(['upload', 'layer'], function () {
  var upload = layui.upload;
  upload.render({
    elem: '#btnUpload',
    url: API_BASE + '/api/upload/image',
    accept: 'images',
    acceptMime: 'image/*',
    size: 2048,  // KB
    headers: { 'X-CSRFToken': getCsrfToken() },
    before: function () {
      layer.load(1);
    },
    done: function (res) {
      layer.closeAll('loading');
      if (res.code === 0) {
        $('#previewImg').attr('src', res.data.url);
        $('#coverUrl').val(res.data.url);
        $('#uploadText').html('上传成功');
      } else {
        layer.msg(res.msg || '上传失败', { icon: 2 });
      }
    },
    error: function () {
      layer.closeAll('loading');
      layer.msg('上传异常', { icon: 2 });
    }
  });
});

多图:multiple: true, number: 5product-upload.html 等同模式。常用参数:acceptextsauto(手动上传设 false + bindAction)。


10.3 laydate 日期与时间

<input type="text" name="start_date" id="startDate" class="layui-input" placeholder="开始日期">
layui.use('laydate', function () {
  var laydate = layui.laydate;
  laydate.render({
    elem: '#startDate',
    type: 'date',
    max: 0  // 今天之前
  });
  laydate.render({
    elem: '#endDate',
    type: 'date'
  });
  // 范围
  laydate.render({
    elem: '#dateRange',
    range: true,
    rangeLinked: true
  });
});

订单列表 ch09 扩展:范围选完后拆成 start_dateend_date 写入 table.reloadwhere

员工管理 staff-add.html 使用 laydate 选入职日期,同一套 API。


10.4 element:Tab 与折叠

10.4.1 Tab 切换(商品详情多 Tab)

以下内容需解锁后阅读

试读已结束。解锁本章 ¥5.00,或开通年度会员畅读全部教程。
年度会员 ¥199.00/年; 小紫 AI 工作台有效会员 ¥99.00/年

正文仅在服务端鉴权后下发,未付费无法获取下半部分内容。