第 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) |
| 2 | iframe 加载子页(编辑表单首选) |
| 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: 5;product-upload.html 等同模式。常用参数:accept、exts、auto(手动上传设 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_date、end_date 写入 table.reload 的 where。
员工管理 staff-add.html 使用 laydate 选入职日期,同一套 API。