自定义元素必须继承htmlelement或内置元素类,否则报错;需在constructor中调用super()并创建shadow dom;attributechangedcallback需配合observedattributes使用;禁止操作外部dom节点。

自定义元素必须继承 HTMLElement 或内置元素类
不继承标准基类的自定义元素在现代浏览器中会直接报错:Failed to construct 'CustomElement': The result must be an instance of HTMLElement。这是硬性规范,不是可选项。
常见错误是直接写 class MyButton { ... } 然后调用 customElements.define('my-button', MyButton) —— 这会导致元素无法实例化,控制台静默失败或抛出上述错误。
- 独立组件必须继承
HTMLElement:如class MyButton extends HTMLElement - 扩展原生元素需指定
{ extends: 'button' },并在 HTML 中用<button is="my-button"></button> - 构造函数内第一行必须调用
super(),否则 DOM 初始化中断
Shadow DOM 不是可选配件,而是封装前提
没加 Shadow DOM 的自定义元素,内部样式和事件容易污染全局,也违背“封装”本意。很多人跳过这步,结果发现样式被外部 CSS 覆盖、querySelector 意外抓到内部节点、甚至监听器绑定错位。
正确做法是在 constructor 中立即创建 Shadow DOM:
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const wrapper = document.createElement('div');
wrapper.innerHTML = `<slot></slot>`;
shadow.appendChild(wrapper);
}
-
mode: 'open'允许 JS 从外部访问 shadowRoot;用'closed'则完全隔离(调试困难,慎用) - 务必用
<slot></slot>承载传入的子内容,否则自定义标签里写的文本或子元素不会渲染 - 所有样式必须注入 shadowRoot,例如
shadow.innerHTML = '<style>div{color:red}</style>' + html
attributeChangedCallback 需配合 observedAttributes 显式声明
想响应 my-counter value="5" 这类属性变更?光写 attributeChangedCallback 没用。浏览器根本不会触发它,除非你在类上定义静态 getter observedAttributes。
典型漏写场景:value 属性变了,但组件 UI 没更新,控制台也无报错——因为变更监听根本没注册。
- 必须返回字符串数组:
static get observedAttributes() { return ['value', 'disabled']; } -
attributeChangedCallback(attr, oldVal, newVal)中,oldVal和newVal均为字符串,数值型属性需手动parseInt或parseFloat - 首次初始化时,若属性已在 HTML 中声明(如
<my-counter value="10"></my-counter>),该回调会被触发一次
生命周期方法里禁止同步操作 DOM 外部节点
connectedCallback 是最常被滥用的方法。有人在里面直接调用 document.getElementById('main') 并修改其内容——这看似可行,实则埋下竞态隐患:如果该外部节点还没加载,操作就失效;如果多个自定义元素同时执行,还可能互相干扰。
真正安全的做法是只操作自身影子树,或通过事件通信向外传递意图:
- 用
this.dispatchEvent(new CustomEvent('ready', { detail: this }))通知父容器 - 避免在
disconnectedCallback中清理全局定时器或事件监听器,除非你明确知道它们归属且已做好引用管理 -
adoptedCallback极少用,但一旦涉及document.adoptNode场景(如 iframe 内迁移),必须处理跨上下文资源释放
innerHTML。这些操作都会绕过生命周期、破坏 Shadow DOM 隔离,最终表现为行为不可预测、调试成本陡增。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











