data-*属性必须全小写加连字符命名,否则浏览器解析时直接忽略;读写须统一用setattribute/getattribute,混用导致状态不一致;值恒为字符串,存取需手动类型转换与json解析,禁存敏感信息。

data-* 属性不是“随便加个属性就行”的快捷键,而是有硬性命名规则和访问逻辑的原生机制——写错名字,JS 就读不到;混用 API,状态就会错乱。
data-* 属性名为什么写对了还是读不到
根本原因:浏览器只认全小写 + 连字符的命名。写成 data-userId、data_user_id、data-UserID,DOM 解析时直接忽略,DevTools 里都看不到,dataset.userId 当然返回 undefined。
-
data-user-id✅ → JS 中用el.dataset.userId -
data-api-url✅ → JS 中用el.dataset.apiUrl -
data-2024-report✅ → 但必须用el.dataset["2024Report"](点号无法访问数字开头) -
data-productName❌ → 浏览器不解析,等同于没写
dataset 读写和 getAttribute/setAttribute 能不能混用
不能。混用会立刻导致值不一致:dataset.foo = "a" 只改内存副本;setAttribute("data-foo", "b") 才真正更新 DOM。下次读 dataset.foo 还是 "a",而 getAttribute("data-foo") 返回 "b" —— 缓存未刷新。
- 读取优先用
el.dataset.xxx(语义清晰、自动驼峰转换) - 写入必须用
el.setAttribute("data-xxx", "value")(否则无法持久化) - 判断是否存在:先用
"xxx" in el.dataset,再取值,避免undefined引发错误 - 删除属性:用
delete el.dataset.xxx,比removeAttribute("data-xxx")更安全
存 JSON 或布尔值时最容易踩的坑
dataset 暴露出来的永远是字符串。存 data-is-pending="false",读出来是字符串 "false",不是布尔值 false;存 data-config='{"theme":"dark"}',读出来是字符串,不是对象。
- 布尔判断别直接
if (el.dataset.isPending),得写成el.dataset.isPending === "true" - JSON 字符串需手动
JSON.parse(el.dataset.config),且必须加try/catch - 敏感信息(如权限列表、token)禁止塞进
data-,HTML 源码可被任意查看 - 高频读写(比如滚动监听中反复取
dataset.offset)建议缓存到变量,避免重复 DOM 访问
最常被忽略的一点:服务端渲染(SSR)或框架(如 Vue/React)中,data- 不会自动透传到客户端 dataset,需显式处理;另外,IE11 支持 dataset,但不支持动态新增属性后立即映射——首次设置仍得靠 setAttribute。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











