<p>data-* 属性必须用小写字母和连字符命名,禁止驼峰或下划线;JS 中通过 dataset 读取,自动转驼峰;属性值恒为字符串;避免存储敏感信息或大量数据。</p>

data-* 属性必须用连字符分隔单词
HTML 的 data-* 属性名不支持驼峰或下划线,浏览器会把所有非字母数字字符(除连字符外)视作非法。比如 data-userId 或 data_user_name 都不会被解析为有效 data 属性——前者在 JS 中取不到值,后者直接被忽略。
正确写法只能是小写字母 + 连字符 + 小写字母,例如:
data-user-id="123" data-api-endpoint="/v2/users" data-is-active="true"
- 连字符后必须紧跟字母,
data-1st-item是无效的(以数字开头) - 属性值始终是字符串,即使写
"true"或"42",JS 里拿到的仍是"true"和"42" - 多个单词必须全用连字符连接,
data-full-name✅,data-fullname❌(语义模糊,且易与未来标准属性冲突)
JavaScript 中读取 data 属性要用 dataset,不能直接 getAttribute
dataset 是专为 data-* 设计的 API,它自动处理连字符转驼峰,并过滤掉非法前缀。直接用 getAttribute('data-user-id') 虽然能取到原始字符串,但绕过了标准化转换逻辑,容易出错。
例如 HTML 中有:<div id="user" data-user-id="789" data-api-endpoint="/api/profile"></div>
立即学习“前端免费学习笔记(深入)”;
JS 中应这样读:
const el = document.getElementById('user');
console.log(el.dataset.userId); // "789"(自动转驼峰)
console.log(el.dataset.apiEndpoint); // "/api/profile"-
dataset的键名是自动去除data-前缀、并将后续连字符后首字母大写的驼峰形式,data-user-id→userId - 如果属性名含数字开头(如
data-2fa-enabled),JS 中只能通过el.dataset['2faEnabled']访问,不能用点号 - 修改
dataset会同步更新 DOM 属性,但反之不成立:手动setAttribute('data-x', 'y')后,dataset.x会立刻反映新值
布尔型 data 属性不要依赖“有无值”来判断真假
很多人误以为 <button data-loading></button> 表示“true”,而 <button data-loading="false"></button> 表示 false——这是错的。HTML 规范中,只要属性存在,无论值是什么,dataset.loading 就返回字符串 ""(空字符串),不是 "false"。
- 显式写
data-loading="true"或data-loading="false",JS 中都得到字符串,需手动转换:JSON.parse(el.dataset.loading)或el.dataset.loading === 'true' - 更稳妥的做法是统一用字符串枚举:
data-status="idle"/data-status="loading"/data-status="error" - 避免用
data-disabled这类与原生属性语义重叠的命名,容易混淆可访问性行为
data 属性不适合存大量数据或敏感信息
data-* 是为组件间轻量通信设计的,不是存储层。把 JSON 字符串塞进 data-config 看似方便,但实际带来三重问题:可读性差、调试困难、潜在 XSS 风险(如果服务端未转义就直出)。
- 超过 2–3 个字段,建议改用
<script type="application/json">块或初始化时通过 JS 注入对象 - 绝对不要放 token、密钥、用户手机号等,这些会在 DOM 树中明文可见,任何前端脚本都能读取
- 服务端渲染时若动态写入 data 属性,务必对值做 HTML 实体编码,否则
data-name="O'Reilly"会导致属性截断
真正需要灵活性的地方,往往该交给组件 props 或 context,而不是靠 data 属性硬塞。



















