layui下拉框需用lay-data属性替代data-,其值为合法json字符串,渲染后自动转为对应data-属性;动态添加option时须设置lay-data并调用form.render('select')。

layui下拉框如何给option添加data-*属性
layui 的 select 组件默认不支持直接在 HTML 中写 data-* 属性(比如 <option value="1" data-id="101">选项</option>),因为 layui 会用 JS 重渲染 DOM,原始标签里的自定义属性会被丢弃。想保留或动态加,得绕过原生渲染逻辑。
用 lay-data 属性替代 data-*(官方推荐方式)
layui 从 2.8+ 开始支持 lay-data 属性,它会在渲染后自动转为对应 option 元素的 data-*,是唯一被框架识别并透传的入口。
实际写法如下:
<select name="city" lay-filter="citySelect"><option value="">请选择</option>
<option value="bj" lay-data='{"code":"CN110000","level":1}'>北京</option>
<option value="sh" lay-data='{"code":"CN310000","level":1}'>上海</option></select>
注意几点:
-
lay-data值必须是合法 JSON 字符串,双引号需转义(如上例用") - 渲染后,对应
<option></option>元素会生成data-code、data-level等属性 - 不能用
data-*直接写,否则会被忽略 - 如果用 JS 动态追加 option,也要用
lay-data,不是dataset
监听 change 时读取自定义属性
用户选中后,可通过 form.on('select(filterName)') 拿到当前选中的 option 元素,再用 elem.selectedOptions[0].dataset 读取值。
示例:
form.on('select(citySelect)', function(data){
var elem = data.elem; // select DOM
var selectedOpt = elem.selectedOptions[0];
console.log(selectedOpt.dataset.code); // "CN110000"
console.log(selectedOpt.dataset.level); // "1"(字符串)
});
注意:
-
selectedOptions[0]是标准 API,比 jQuery 的find(':selected')更可靠 -
dataset返回的是字符串,数值需手动parseInt或JSON.parse - 若用
lay-data里写了嵌套对象(如{"extra":{"type":"admin"}}),dataset.extra会是字符串,需再解析
动态添加 option 并带自定义属性
如果要 JS 动态插入带属性的 option,不能直接 innerHTML,必须用 layui.form.render() 前确保 lay-data 已存在。
正确做法:
// 假设 select 已有 id="citySelect"
var selectElem = document.getElementById('citySelect');
var opt = document.createElement('option');
opt.value = 'gz';
opt.innerHTML = '广州';
opt.setAttribute('lay-data', '{"code":"CN440100","level":2}');
selectElem.appendChild(opt);
form.render('select'); // 必须触发重渲染,否则 lay-data 不生效
容易踩的坑:
- 漏掉
form.render('select')→ 自定义属性不会出现在最终 DOM 中 - 用
opt.dataset.xxx = xxx→ layui 渲染时会清空,无效 - 在
form.on回调里修改lay-data再 render → 不触发重新解析,属性不会更新
lay-data 这一条路,其他方式基本绕不开重渲染和属性丢失问题。真正要用好,关键是把 lay-data 当成唯一数据载体,而不是试图 patch 原生 DOM 行为。











