必须在渲染前写死 data-id,否则 form.render() 后操作无效;读取时须用 selectedopt.dataset.id,禁用 jquery .data()。

必须在渲染前写死 data-id,渲染后加无效
Layui 的 select 渲染时会隐藏原生 <select></select>,用伪 DOM(.layui-select-dropdown)模拟下拉菜单,真实 <option></option> 节点不参与交互、也不被浏览器重新解析。所以你在 form.render() 之后再用 querySelector 或 jQuery 去给 option 补 data-id,完全没用——那些 DOM 不是实际响应选择的节点。
正确做法只有一条:在 HTML 字符串拼接或后端模板输出阶段,就把 data-id 写进原始 <option></option> 标签里。
- 后端返回 JSON 数组时,前端拼字符串要带
data-id:options += '<option value="' + item.value + '" data-id="' + item.id + '">' + item.text + '</option>';
- 若用 axios 动态加载,确保后端返回的数据结构里含
id字段,并在循环中注入:response.data.list.forEach(item => {<br> $('#mySelect').append(`<option value="${item.value}" data-id="${item.id}">${item.label}</option>`);<br>});<br>form.render('select'); - 不要用
setAttribute('data-id', ...)在form.on('select(...)')回调里反向设置——那是对已渲染完的伪 DOM 操作,白忙活
dataset.id 是读取自定义属性的唯一可靠方式
用户选中后,Layui 的 form.on('select(filter)') 回调中,data.elem 是原生 <select></select> 元素,它能访问到所有原始 <option></option> 上的 data-* 属性。但必须用 dataset API 读取,不能用 getAttribute 或 jQuery 的 .data()。
常见错误是写成 $(data.elem).find(':selected').data('id') —— jQuery 的 .data() 会尝试解析 JSON、缓存值、忽略大小写,行为不可控;而 dataset.id 直接映射 HTML 中的 data-id,稳定且无副作用。
- 正确读法:
form.on('select(myFilter)', function(data) {<br> const select = data.elem;<br> const selectedOpt = select.options[select.selectedIndex];<br> console.log(selectedOpt.dataset.id); // 字符串,如 "1024"<br>}); - 如果后端传的是数字 ID,记得手动转类型:
parseInt(selectedOpt.dataset.id, 10) -
selectedOpt.dataset.id和data.value可能不同——前者是你存的业务 ID,后者是value属性值,别混用
动态更新 option 时,data-id 也得同步重写
当需要清空并重新填充下拉项(比如级联选择:选了省,再加载市),很多人只清空 innerHTML 或用 empty().append(),却忘了新插入的 <option></option> 必须包含 data-id,否则后续读取会是 undefined。
- 清空后重新生成选项时,每一条都要显式带上
data-id:$('#citySelect').empty();<br>cities.forEach(city => {<br> $('#citySelect').append(`<option value="${city.code}" data-id="${city.id}">${city.name}</option>`);<br>});<br>form.render('select'); - 别依赖
form.render()自动补属性——它只负责样式重绘,不处理数据绑定 - 如果用
lay-data配置项(如lay-data="{data: [...]}"),注意该方式不支持data-*注入,必须走 HTML 字符串路径
title 属性和 data-id 一样,原生写无效
有人想用 title 实现 hover 提示,直接写 <option title="xxx"></option>,结果 hover 没反应。原因相同:Layui 渲染后不使用原生 option 的 title,而是靠伪 DOM 显示文本。所以 title 也得像 data-id 一样预埋为 data-title,再在回调里手动设到显示层:
- HTML 中写:
<option value="bj" data-title="北京市,直辖市">北京</option> - 回调里注入:
layui.$(data.elem).next('.layui-form-select').find('input').attr('title', selectedOpt.dataset.title); - 注意
data-title值里不能含双引号或,否则破坏 HTML 结构;服务端需提前转义
.data(),坚持用原生 dataset。这两步漏掉任何一环,data-id 就等于没加。











