dataset 属性存储在元素的 dataset 对象中,不写入 html 源码;需符合命名规范(小写字母、数字、连字符,不以数字开头),连字符自动转驼峰;编辑器中需配置白名单并同步 setattribute 才能持久化。

dataset 属性到底存到哪了?
它不写进 HTML 源码,而是映射到元素的 dataset 对象上——也就是说,你在 HTML 里写 data-id="123",JS 里读的是 element.dataset.id,而不是 element.getAttribute('data-id')。这点容易混淆,尤其当你用编辑器实时预览时,看不到 DOM 中新增的属性,只看到原始 HTML。
怎么写 data-* 属性才被 dataset 识别?
必须符合命名规范:只允许小写字母、数字、连字符(-),且不能以数字开头。连字符会自动转成驼峰式键名。
-
data-user-id→dataset.userId -
data-api-url→dataset.apiUrl -
data-1st-name❌(以数字开头,无效) -
data-Name❌(含大写字母,会被忽略)
编辑器里直接手敲没问题,但某些富文本编辑器(如 TinyMCE、CKEditor)可能过滤或转义 data- 属性,需检查其配置是否启用 validAttributes 白名单。
编辑器中动态添加 dataset 的坑
别在编辑器内容初始化后硬塞 dataset——它不是可序列化的 DOM 属性。你调用 element.dataset.foo = 'bar',HTML 源码不会更新,导出或保存时这部分元数据就丢了。
- 要持久化,必须同步写回
setAttribute('data-foo', 'bar') - 编辑器监听内容变化时(如
input或change事件),优先用getAttribute/setAttribute操作原始属性 -
dataset适合运行时临时读写,比如拖拽排序时标记节点顺序:el.dataset.sortIndex = String(i),但提交前得转成属性落盘
dataset 和自定义属性的性能差异
对普通页面影响微乎其微,但在高频操作场景(如每秒渲染几十个带 data-* 的列表项),dataset 访问比 getAttribute 快约 15–20%,因为它是原生属性映射,无需字符串解析。
不过,如果编辑器本身用了虚拟 DOM(如 Slate、ProseMirror),频繁读写 dataset 可能触发不必要的重排——更稳妥的做法是把元数据存在 JS 对象里,用节点引用当 key,而不是依赖 DOM 属性。
真正麻烦的不是怎么存,而是编辑器导出 HTML 时是否保留这些 data- 属性。很多默认配置会 strip 掉未知属性,得手动加进白名单规则里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











