Custom Elements 和 Shadow DOM 结合实现可复用、样式隔离的 Web 组件:通过定义类继承 HTMLElement 并注册自定义标签,结合 attachShadow 创建独立 DOM 子树,利用 slot 分发内容,实现结构与样式的完全封装,支持属性监听与动态渲染,构建原生 JavaScript 组件。
Custom Elements 和 Shadow DOM 是 Web Components 的两个核心部分,它们让开发者可以创建可复用、封装良好的自定义 HTML 元素。结合使用,能够构建真正独立、样式隔离、行为清晰的组件,直接在原生 JavaScript 中实现类似框架的功能。
Custom Elements 允许你创建新的 HTML 标签,并为其定义对应的行为。通过 customElements.define() 方法注册一个类,这个类继承自 HTMLElement 或其子类,就可以在页面中使用自定义标签。
基本步骤如下:
示例:
class MyCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const title = this.getAttribute('title') || '默认标题';
this.shadowRoot.innerHTML = `
${title}
`;
}
}
customElements.define('my-card', MyCard);
使用方式:
这里是内容
Shadow DOM 提供了一个独立的 DOM 子树,它与主文档 DOM 隔离,包括样式和事件。这意味着你在 Shadow Root 中定义的 CSS 不会影响外部页面,外部样式也不会轻易“穿透”进来。
关键特性:
Shadow DOM 的优势在于:
示例说明 slot 用法:
this.shadowRoot.innerHTML = `
默认内容
`;
对应使用:
这是头部 这是主体内容
Custom Elements 负责定义标签和行为,Shadow DOM 负责封装 UI 和样式,两者结合是 Web Components 的标准实践。
常见模式包括:
增强示例:响应属性变化
class MyToggle extends HTMLElement {
static get observedAttributes() {
return ['on'];
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'on') {
this.render();
}
}
render() {
const isOn = this.getAttribute('on') === 'true';
this.shadowRoot.innerHTML = `
`;
}
}
customElements.define('my-toggle', MyToggle);
使用:
基本上就这些。掌握 Custom Elements 和 Shadow DOM,就能写出不依赖框架、原生支持、可跨项目复用的组件。虽然没有 React 或 Vue 那样丰富的生态,但在轻量级封装、微前端集成、设计系统建设中非常有价值。