data-*属性仅用于初始化传参,不响应变化、不触发重绘;应转为组件内部状态管理,hidden/class才是可靠视图更新通道;监听变更须用customElements+attributeChangedCallback。
别把 data-* 当状态源用,它不响应、不触发重绘,硬绑只会让组件变脆、出错难定位。
浏览器不会监听 data-user-id 的变化,JS 读取它得到的永远是字符串,且 DOM 挂载前访问 this.dataset.id 是 undefined。
data-config='{"theme":"dark"}')必须用 el.getAttribute('data-config') + try/catch 解析,不能直接 JSON.parse(el.dataset.config)
data-theme="dark")挂载后立刻转类型存进组件内部 state.theme = el.dataset.theme === 'dark',后续只读 statedata- 值——服务端和客户端初始值不一致,框架 diff 会丢状态hidden 和 class 是仅有的几个浏览器原生支持“属性变更 → 视图重绘”的全局属性,它们不存状态,但能稳定触发 UI 变化。
el.hidden = true/false,别用 setAttribute('hidden', '') —— property 和 attribute 容易不同步el.classList.toggle('state-loading'),比拼接 className 安全,且能触发 CSS 重绘title 或 lang 控制显示逻辑——它们只影响辅助技术,不触发重绘原生 <div> 加了 data-count,浏览器根本不会通知 JS “它变了”。唯一可控路径是自定义元素。
立即学习“前端免费学习笔记(深入)”;
observedAttributes 里声明要监听的 data- 名,如 ['data-count', 'data-config']
attributeChangedCallback(attr, oldVal, newVal) 里做类型转换和状态同步,newVal 仍是字符串oldVal === null 来区分初始化 vs 更新真正容易被忽略的是:你写的 data- 值是否在 SSR 和 CSR 间保持一致;以及,哪怕用了 customElements,attributeChangedCallback 里不做防抖或节流,高频变更照样拖垮渲染帧率。