Web Components 是浏览器原生标准,含 Custom Elements(需含短横线、继承 HTMLElement、用 define 注册)、Shadow DOM(open/closed 模式、slot 分发、样式隔离)和 template 克隆机制,但无内置响应式,通信依赖属性/事件。

Web Components 不是“教程式框架”,而是浏览器原生支持的一套标准,用它创建的组件天然可重用、无框架依赖、能跨项目移植——但直接手写完整生命周期和样式隔离,容易踩坑。
什么是 Custom Elements?
Custom Elements 是 Web Components 的核心之一,允许你定义自己的 HTML 标签,比如 <my-button> 或 <data-table>。它必须继承 HTMLElement,且标签名里必须含短横线(-),否则浏览器会拒绝注册。
- 注册必须在
customElements.define()中完成,且只能注册一次;重复注册会抛错Failed to execute 'define' on 'CustomElementRegistry': the name "xxx" has already been used - 构造函数中不能直接操作
this.shadowRoot(因为此时可能还没 attach),应改用connectedCallback - 若需响应属性变化,得显式声明
observedAttributes静态 getter,并实现attributeChangedCallback
如何用 Shadow DOM 实现样式与结构隔离?
Shadow DOM 是让组件真正“自包含”的关键:它的样式不会泄漏出去,外部样式也进不来。但默认是 open 模式,意味着可通过 el.shadowRoot 访问——如果不想被外部篡改,应设为 closed(不过调试会变困难)。
- 创建 shadow root 时推荐用
this.attachShadow({ mode: 'open' }),避免 IE 兼容问题(IE 完全不支持) -
<slot>是内容分发点,但注意:没有name的<slot>只能接收匿名内容;多个具名<slot name="xxx">需配合<div slot="xxx"> - Shadow DOM 内无法用
:host-context(...)响应外部 CSS 主题,更可靠的方式是监听document.documentElement类名变化或使用 CSS 自定义属性传参
HTML Templates + Custom Elements 怎么组合才不翻车?
把模板逻辑写死在 connectedCallback 里容易重复渲染;用 <template> 标签预存结构,再克隆插入,才是稳定做法。
立即学习“Java免费学习笔记(深入)”;
- 模板必须放在
<body>外(如<head>或页面顶部),否则解析时会被当作普通文本丢弃 - 克隆后要调用
content.cloneNode(true),否则后续修改会影响原始模板 - 若模板含
<script>或动态绑定(如{{value}}),Web Components 本身不处理——得自己实现或引入轻量模板引擎 - 事件委托要小心:
shadowRoot是事件边界,默认click不会冒泡到 light DOM,需手动composed: true触发
真正难的不是语法,是状态管理与跨组件通信:Web Components 没有内置响应式系统,父子传参靠属性/事件,兄弟通信得靠自定义事件 + dispatchEvent 向上抛,再由共同父级转发——这点很容易被忽略,结果写出来一堆紧耦合的“伪组件”。











