customElements.define()报错因标签名缺短横线,须用my-button等格式;constructor中不可操作DOM或读属性,应移至connectedCallback;attributeChangedCallback需声明observedAttributes且仅响应setAttribute等操作;Shadow DOM样式需内嵌或用:host伪类。

customElements.define() 报错 “The name must contain a hyphen” 怎么修
标签名没加短横线(-)是注册失败最常见原因,浏览器直接拒绝解析,不是警告而是硬性报错。
-
mybutton、MyButton、my_button全部非法;必须写成my-button、x-input、ds-tooltip - 原生标签名如
button、div、slot也不能复用,否则抛NotSupportedError - 大小写敏感:
My-Button和my-button是两个不同名字,但推荐全小写 + 连字符,避免跨平台差异
constructor 里写 this.innerHTML 或 getAttribute('xxx') 就报错?
构造函数阶段 DOM 还没挂载,连 shadowRoot 都不能 attach,更别说读属性或操作内容。
- 只能做三件事:调
super()、调this.attachShadow({ mode: 'open' })、初始化私有字段(如this._count = 0) - 所有 DOM 操作(
this.innerHTML、this.querySelector)、属性读取(this.getAttribute('value'))、事件绑定,必须挪到connectedCallback里 - 初始 HTML 中的属性值(如
<x-input value="test"></x-input>)在constructor里读不到,getAttribute返回null,别在这儿做逻辑分支
attributeChangedCallback 为什么没触发?
它只响应 setAttribute、removeAttribute 或 HTML 初始属性,对 JS 属性赋值(el.value = 'xxx')完全无感,且必须显式声明监听列表。
- 漏写
static get observedAttributes() { return ['disabled', 'checked']; }→ 回调永远不会执行 -
value这类反射属性(reflecting attribute)不自动同步:设el.value = 'new'不会触发回调,得手动补el.setAttribute('value', 'new') - 初始值(HTML 中写的
checked)会触发一次回调,但oldValue是null,别直接oldValue === newValue判断变更 - 布尔属性值是字符串:
checked属性存在时newValue是''或'true',不存在时是null,建议用newValue !== null判定是否启用
Shadow DOM 样式不生效,或者字体/颜色全丢了
Shadow DOM 天然隔离样式,外部 CSS 不穿透,内部也不继承全局样式 —— 这不是 bug,是设计使然。
立即学习“前端免费学习笔记(深入)”;
- 必须把样式写进 shadowRoot:
this.shadowRoot.innerHTML = '<style>... </style> <div>...</div>',或动态创建style元素 append 进去 - 想控制宿主元素自身样式(比如让
<x-button></x-button>支持class="large"),用:host伪类::host { display: inline-block; } - 想响应属性变化(如
<x-button size="large"></x-button>),用:host([size="large"]) { font-size: 1.2em; } - 不要指望
<style>body { color: red}</style>影响 shadow 内部 —— shadow 里没有body,它只有自己的根节点



















