必须显式加载form模块并确保dom结构正确:用layui.use(['form'], function(){})包裹操作,select父级加class="layui-form",动态插入后用.promise().done()或settimeout延迟渲染,lay-filter严格匹配且赋值前先render。

form.render() 报 “form is not defined” 怎么办
根本不是代码写错了,是 form 模块压根没加载进来。Layui 2.8+ 已禁用 layui.form.render() 这种全局调用方式,必须显式加载模块。
- 确保用
layui.use(['form'], function(){})包裹所有form相关操作,不能只引入layui.js就完事 - 如果在
$.ajax、layer.open的回调里调用,form必须是闭包内可访问的变量(比如var form = layui.form),别在外部直接写form.render() - 打开控制台,检查是否报
layui is not defined或Cannot read property 'use' of undefined—— 那说明 Layui 自身都没加载成功
DOM 插入后 form.render('select') 还是原生样式
不是渲染失败,是 form 模块根本没“看到”这个 select —— 它不在扫描范围内。
-
select的最近父级必须有class="layui-form",不能只靠后代自动识别;错误写法:<div><select></select></div>,正确写法:<div class="layui-form"><select></select></div> - 动态插入后立即调用
form.render('select')很可能 DOM 还没真正挂载;推荐用$('#container').html(htmlStr).promise().done(() => form.render('select')),或退一步用setTimeout(() => form.render('select'), 0) -
lay-filter必须严格匹配:大小写、空格、引号全算;HTML 里是lay-filter="userType",JS 里就不能写成form.render('select', 'usertype')
赋值后 UI 不变但 form.val() 返回值正确
DOM 和内部状态都对了,视觉卡住,90% 是 lay-filter 对不上,或者渲染和赋值顺序错了。
- 必须按三步走:
append新option→form.render('select', 'xxx')→form.val('xxx', {name: 'value'});漏掉第二步,UI 就不会刷新 -
form.val()只对已通过form.render()处理过的元素生效;如果select上没有lay-id属性(开发者工具里看),说明form.render()根本没跑成功 - 不要用
select.value = 'x'或$('select').prop('value', 'x')赋值,这只会改 DOM,不触发 Layui 内部状态同步
Vue 或异步场景下 form.render() 失效
Vue 的虚拟 DOM 补丁和 Layui 的 DOM 扫描不同步,不是 bug,是机制冲突。
- 在 Vue 组件里,别在
mounted里一次性调form.render();改用updated钩子,每次数据重绘后补一次:updated() { layui.use(['form'], () => form.render()) } - Layer 弹窗内容是动态插入
body的,初始页面结构里根本没有它;必须在layer.open的success回调里执行渲染,且优先指定filter,避免误刷主页面 - 复合组件如
laydate、upload、textarea不归form.render()管;textarea只需保证class="layui-textarea",其他必须单独初始化,比如新插入的日期控件要再跑一遍laydate.render({elem: '#date1'})
lay-filter 拼错一个字母,form.render() 就静默跳过;DOM 插入还没完成就急着渲染,等于对着空气刷样式。











