HTML data属性命名须用小写字母、数字、连字符且以字母开头,推荐kebab-case;dataset读取值恒为字符串,需显式类型转换;高频场景应缓存dataset值;SSR时需确认框架是否保留data属性;data属性仅适合存初始配置,非状态容器。

data属性命名要符合HTML规范,不能含空格或特殊符号
HTML data- 属性只允许小写字母、数字、连字符(-),且必须以字母开头。像 data-sort-by、data-sort-order 是合法的;data-sortBy、data-sort order、data-sort@field 都会被浏览器忽略或解析失败。
实际使用中建议统一用 kebab-case(短横线分隔),和 CSS 自定义属性风格一致,也便于 JS 中通过 dataset 自动转换为 camelCase 访问:
<div data-sort-by="price" data-sort-order="desc"></div>
JS 里读取时:el.dataset.sortBy → "price",el.dataset.sortOrder → "desc"。
dataset读取值始终是字符串,注意类型转换
dataset 返回的所有值都是字符串,哪怕你写的是 data-page="1 或 data-asc="true",JS 拿到的仍是 "1" 和 "true"。直接用于比较或布尔判断会出错:
立即学习“前端免费学习笔记(深入)”;
-
if (el.dataset.sortOrder === true)→ 永远 false -
el.dataset.page + 1→"11"(字符串拼接)而不是2
推荐显式转换:
const sortBy = el.dataset.sortBy || 'id';<br>const isAsc = el.dataset.sortOrder === 'asc';<br>const page = Number(el.dataset.page) || 1;
避免在循环中反复读取 dataset,影响性能
每次访问 el.dataset.xxx 都触发 DOM 属性解析,高频操作(如排序动画、滚动监听)中反复读取会造成轻微但可测的开销。
更稳妥的做法是:在初始化或参数变更时一次性提取并缓存:
const sortConfig = {<br> by: el.dataset.sortBy || 'id',<br> order: el.dataset.sortOrder === 'asc' ? 'asc' : 'desc',<br> limit: Number(el.dataset.limit) || 10<br>};后续逻辑直接用 sortConfig.by,不再触达 dataset。
服务端渲染时 data 属性可能被框架过滤,需确认输出策略
Next.js、Nuxt 等 SSR 框架默认会剥离非标准属性,除非显式声明为“安全”。比如 React 中直接写 <div data-sort-by="name"> 在服务端渲染后可能消失。<p>解决方式取决于框架:</p>
<ul>
<li>React:用 <code>suppressHydrationWarning 或改用 data-* 属性加 dangerouslySetInnerHTML(不推荐)
data- 开头,通常保留;但若用 React.createElement 动态生成,需检查是否被 react-dom/server 过滤上线前务必用「查看页面源代码」确认 data- 属性真实存在,而非仅在 DevTools 的运行时 DOM 中看到。
data 属性不是状态容器,它只适合存初始配置或轻量元信息;频繁变动的排序状态应交由 JS 变量或 URL 参数管理,否则容易和 DOM 同步脱节。



















