页面配置必须挂载在标签上,如,因其在html解析最早阶段即存在,document.documentelement.dataset可立即访问;为次选,避免挂载在业务容器中。

页面配置必须挂载在 或 上,用 data-* 属性传字符串或 JSON 序列化值,不能塞进 class、id 或自定义非标准属性里——否则 JS 读不到,SSR 渲染后也丢失。
配置该挂在哪一层 DOM 节点上
优先写在 标签上:。它在 HTML 解析最早阶段就存在,document.documentElement.dataset 在任意脚本中可立即访问,不依赖 DOM 就绪。
是次选,适合只供前端 JS 使用、且无需 SSR 首屏直出的配置。别挂在某个业务容器(比如 <div id="app">)上——组件未挂载时就读不到,多实例还会冲突。<ul>
<li>服务端模板(如 EJS、Jinja2)输出时,对 JSON 值必须做 HTML 实体转义,例如:<code>data-config=""{"theme":"dark"}""
data-token、data-secret-key 绝对禁止——源码里明文可见,等同于泄露data-* 属性命名和读取的硬规则
写错名字,JS 就读不到。data-userId、data_user_id、data-UserID 全部无效:浏览器只认全小写 + 连字符形式,且自动把连字符后首字母转驼峰。
正确示例:data-api-url → JS 中为 el.dataset.apiUrl;data-2024-report → 必须用 el.dataset["2024Report"](点号无法访问数字开头)。
- 读取一律用
el.dataset.xxx,语义清晰且自动转换命名 - 写入必须用
el.setAttribute("data-xxx", "value"),否则只改内存副本,DOM 不更新 - 判断是否存在,先写
"xxx" in el.dataset,再取值,避免undefined导致报错 - 删除用
delete el.dataset.xxx,比removeAttribute("data-xxx")更安全
存 JSON、布尔值、数字时怎么防坑
dataset 暴露的永远是字符串。存 data-is-pending="false",读出来是字符串 "false",不是布尔 false;存 data-config='{"theme":"dark"}',读出来是字符串,不是对象。
- 布尔判断别用
Boolean(el.dataset.isPending),改用el.dataset.isPending === "true" - 数字转换用
+el.dataset.count或Number(el.dataset.count),别直接=== 0 - JSON 数据必须手动
JSON.parse(el.dataset.config || "{}"),且加try/catch——服务端漏转义会直接导致语法错误 - 多值场景(如权限列表)用空格分隔:
data-perms="read write delete",再用.split(" ")处理,比存 JSON 数组更鲁棒
SSR 和框架环境下的特殊处理
服务端渲染时,首次 JS 执行前 dataset 是空的;React/Vue 默认不透传 data-* 到根节点,必须显式处理。
SSR 安全读值方式:el.getAttribute("data-xxx") —— 它返回原始字符串,不依赖 dataset 初始化时机。
- Vue 中需在根组件
data-属性上加v-bind显式绑定,或通过provide/inject透传 - React 中 JSX 支持原生
data-*,但注意不要用data-config={obj}直接传对象,必须先JSON.stringify - 构建时能静态确定的配置(如版本号、CDN 域名),建议用 webpack DefinePlugin 注入,而非 runtime 读 DOM
最易被忽略的是路径解析上下文:如果配置里有 ,它相对于当前 HTML 文档 URL,不是相对于 JS 文件位置。单页应用路由切换后,这个相对路径可能突然失效——绝对路径才是稳解。











