第 8 章 · Layui 表单组件与数据校验
本章目标:掌握 Layui form 模块对 input、select、radio、checkbox、switch 的渲染与取值;使用 form.verify 自定义校验规则与 form.on('submit') 拦截提交;结合 jQuery 完成动态赋值与 Ajax 提交;在 admin-demo 中实现商品编辑表单完整页面。
学时建议:3.5 小时(含 70 分钟跟练)
前置:本模块 ch07(布局骨架);ch04(jQuery Ajax);了解 REST 风格接口。
8.1 form 模块工作原理
Layui 不会自动美化原生 <form>,需:
- 给表单加
class="layui-form" - 给控件加 Layui 约定结构(
layui-form-label+layui-input-block) - 在
layui.use(['form'])后调用form.render()渲染 select、radio 等 - 动态改 DOM 后再次
form.render('select')等局部渲染
layui.use('form', function () {
var form = layui.form;
form.render(); // 首次渲染整个表单
});
| 场景 | 必须 render |
|---|---|
| 页面初次加载 | form.render() |
| Ajax 填充 select 选项后 | form.render('select') |
| 弹窗内表单 | 弹窗 success 回调里 render |
| checkbox 动态勾选 | form.render('checkbox') |
iframe 弹窗编辑页在打开后常需 setTimeout 再赋值,原因包括子页 form 尚未 render(ch09 商品列表编辑弹窗即如此)。
8.2 表单项结构规范
<form class="layui-form" lay-filter="productForm" id="productForm">
<div class="layui-form-item">
<label class="layui-form-label">商品名称</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required"
placeholder="请输入商品名称" autocomplete="off" class="layui-input">
</div>
</div>
</form>
| 区域 | 类名 | 说明 |
|---|---|---|
| 行 | layui-form-item | 一行一项或一组 |
| 标签 | layui-form-label | 固定宽度,可 layui-form-label-sm |
| 控件区 | layui-input-block | 占满剩余宽度 |
| 行内 | layui-inline + layui-input-inline | 搜索栏多字段 |
lay-filter:表单唯一标识,供 form.val / form.on 使用,同一页多表单时必填。
8.3 基础控件详解
8.3.1 文本 input
<input type="text" name="name" class="layui-input" placeholder="名称">
<input type="number" name="price" class="layui-input" step="0.01">
<input type="password" name="pwd" class="layui-input">
<textarea name="desc" class="layui-textarea" placeholder="简介"></textarea>
lay-verify 可叠加:lay-verify="required|price"。
8.3.2 select 下拉
<select name="category_id" lay-verify="required" lay-search="">
<option value="">请选择分类</option>
<option value="1">生鲜</option>
<option value="2">百货</option>
</select>
lay-search 开启可搜索下拉。动态选项:
var html = '<option value="">请选择</option>';
categories.forEach(function (c) {
html += '<option value="' + c.id + '">' + c.name + '</option>';
});
$('select[name="category_id"]').html(html);
form.render('select');
8.3.3 radio 与 checkbox
<input type="radio" name="status" value="1" title="上架" checked>
<input type="radio" name="status" value="0" title="下架">
<input type="checkbox" name="tags" value="hot" title="热卖" lay-skin="primary">
<input type="checkbox" name="tags" value="new" title="新品" lay-skin="primary">
radio 同名单选;checkbox 多选提交时需在 JS 里合并为数组。
8.3.4 switch 开关
<input type="checkbox" name="use_self_payment" lay-skin="switch"
lay-text="自营收款|平台收款" value="1">
开关未选中时不会出现在 data.field,需在 submit 里补 0(行业常见 SKU 收款方式逻辑相同)。
8.4 内置校验与 form.verify
8.4.1 常用内置规则
| lay-verify | 说明 |
|---|---|
required | 非空 |
phone | 手机号 |
email | 邮箱 |
url | URL |
number | 数字 |
date | 日期 |
identity | 身份证 |
8.4.2 自定义 verify
form.verify({
title: function (value) {
if (value.length < 2 || value.length > 60) {
return '商品名称长度 2~60 字';
}
},
price: function (value) {
if (!value) return '请输入价格';
if (!/^\d+(\.\d{1,2})?$/.test(value)) {
return '价格最多两位小数';
}
if (parseFloat(value) <= 0) return '价格须大于 0';
},
stock: function (value) {
if (!/^\d+$/.test(value)) return '库存须为非负整数';
}
});
规则函数返回字符串即为错误信息;返回 undefined 表示通过。多个规则用 | 连接:lay-verify="required|title"。
8.4.3 提交按钮
<button type="submit" class="layui-btn" lay-submit lay-filter="saveProduct">
保存商品
</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
仅 lay-submit + lay-filter 的按钮会触发校验;普通 button 不会。
8.5 form.on('submit') 与阻止默认提交
form.on('submit(saveProduct)', function (data) {
var field = data.field; // 已校验通过的字段对象
// field.name, field.price, field.status ...
// switch 未选中时补默认值
if (!field.use_self_payment) {
field.use_self_payment = '0';
}
saveProductAjax(field);
return false; // 阻止表单原生 submit 与页面跳转
});
| 事件 | 触发条件 |
|---|---|
submit(filter) | 校验通过后 |
| 校验失败 | 自动标红,不触发 submit |
搜索表单(ch09)同样用 form.on('submit(search)'),内部 table.reload 而非 POST 整页。