data-*属性名必须全小写加连字符,如data-user-id;驼峰、下划线或大写均无效,浏览器忽略解析;dataset读取自动转驼峰,但仅限合法命名,含数字开头需方括号访问,且值恒为字符串,类型转换须手动处理。

data-* 属性名必须全小写+连字符,不能用驼峰或下划线
浏览器只识别 data-user-id、data-api-endpoint 这类命名;dataUserId、data_user_id、data-UserID 全部无效——DOM 解析时直接忽略,dataset 里根本不会出现对应字段。
常见错误现象:element.dataset.userId 返回 undefined,但 HTML 里明明写了 data-userId="123";根源就是命名不合规,浏览器压根没把它当 data 属性处理。
- 正确写法:
data-order-status→ JS 中读作element.dataset.orderStatus - 含数字开头的(如
data-2024-year)只能用方括号访问:element.dataset["2024Year"] - 连续连字符(如
data-foo--bar)会被转成fooBar,但语义模糊,不推荐
dataset 是只读代理,改值必须用 setAttribute
element.dataset.foo = "bar" 看似生效,其实只是操作内存副本;刷新页面后,原始 HTML 的 data-foo 值不变。真正要持久化更新 DOM 属性,必须调用 setAttribute。
- 读取优先用
element.dataset.xxx(自动转驼峰、语义清晰) - 写入必须用
element.setAttribute('data-xxx', 'value') - 混用会出问题:
dataset.foo = 'a'后再setAttribute('data-foo', 'b'),dataset.foo仍返回'a'—— 因为 dataset 不是双向绑定,只是读取时映射
dataset 返回的永远是字符串,类型转换得自己来
无论你在 HTML 里写 data-count="42" 还是 data-active="true",通过 dataset.count 或 dataset.active 拿到的都是字符串 "42" 和 "true"。
-
if (el.dataset.active === true)→ 永远false -
el.dataset.count + 1→ 得到"421"(字符串拼接) - 正确做法:
const count = Number(el.dataset.count),const isActive = el.dataset.active === "true"
getAttribute 才是兜底方案,尤其面对特殊字符或空格
当属性名含下划线(data-user_name)、点号、或连续短横线时,dataset 完全无法访问;值里有前后空格或换行符时,dataset 会自动 trim(),而 getAttribute() 返回原始字符串。
-
el.getAttribute('data-user_name')可用,el.dataset.user_name一定undefined - 服务端渲染输出 JSON 字符串前,必须 HTML 实体编码,否则
JSON.parse(el.getAttribute('data-config'))易报SyntaxError - IE11 对连字符转驼峰有兼容性 bug(如
data-user-id的dataset.userId可能取不到),此时降级用getAttribute更稳
最常被忽略的一点:data-* 是上下文容器,不是状态管理器。存 token、大段 JSON、用户邮箱?全在源码里明文可见。它只适合轻量、静态、非敏感的上下文信息——比如预埋 ID、灰度开关、API 路径前缀。别的,交给 JS 变量或 Map。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











