Web Components 基础

Web Components 基础 2.8 Web Components 基础Web Components 是浏览器原生支持的组件化标准体系允许开发者创建可复用、强封装的自定义 HTML 元素核心由 Shadow DOM、自定义元素、HTML Template 三大技术构成。它实现了组件级的样式隔离、结构封装与原生级复用无需依赖前端框架即可实现跨项目、跨技术栈的组件复用是原生前端组件化的底层标准。2.8.1 Shadow DOM 影子 DOMShadow DOM 是 Web Components 的核心封装机制它可以在普通 DOM 元素内部创建一个独立、与外部文档 DOM 树隔离的影子 DOM 子树。内部的样式、DOM 结构不会污染外部页面外部的全局样式也不会渗透到组件内部从浏览器原生层面解决了组件样式冲突、DOM 结构干扰的问题。一、基础使用语法通过元素的attachShadow()方法挂载影子 DOM返回影子根节点shadowRoot后续所有 DOM 操作都在影子根内部完成。// 获取宿主元素 const host document.querySelector(.component-host); // 挂载影子 DOM const shadowRoot host.attachShadow({ mode: open // 开放模式外部可访问影子根 }); // 向影子 DOM 中插入结构与样式 shadowRoot.innerHTML style .card { color: #1677ff; } /* 内部样式仅在影子 DOM 内生效不会影响外部 */ /style div classcard slot/slot /div ;二、mode 封装模式Shadow DOM 提供两种封装模式对应不同的外部访问权限mode取值外部访问性适用场景open外部可通过host.shadowRoot访问影子 DOM 内部通用组件场景便于外部交互与调试closed外部无法获取影子根host.shadowRoot返回null强封装场景禁止外部操作组件内部结构三、核心特性样式完全隔离外部 CSS 选择器无法选中影子 DOM 内部元素内部样式也不会泄露到外部彻底解决组件样式污染问题。DOM 结构隔离外部querySelector等 DOM 查询方法无法穿透影子 DOM内部 DOM 独立维护。事件重定向内部事件冒泡到外部时event.target会自动指向宿主元素隐藏内部结构细节保持封装性。插槽内容分发通过slot标签接收外部传入的子内容实现组件内容的灵活扩展。四、slot 插槽机制插槽是 Shadow DOM 的内容分发接口用于承载外部传入的子元素支持默认内容与具名插槽。!-- 外部使用组件时传入内容 -- custom-card span slottitle卡片标题/span p卡片正文内容/p /custom-card // 影子 DOM 内部定义插槽位置 shadowRoot.innerHTML div classcard h3 classcard-title slot nametitle默认标题/slot /h3 div classcard-body slot默认正文内容/slot /div /div ;2.8.2 自定义元素基础自定义元素Custom Elements允许开发者定义全新的 HTML 标签通过继承原生HTMLElement类实现自定义标签的行为与业务逻辑配合 Shadow DOM 即可实现完整的原生组件是 Web Components 的核心载体。一、定义与注册流程创建自定义元素类继承HTMLElement基类通过customElements.define()注册标签标签名必须包含横杠避免与原生 HTML 标签冲突// 定义自定义元素类 class CustomButton extends HTMLElement { constructor() { super(); // 必须先调用父类构造函数 // 挂载 Shadow DOM const shadow this.attachShadow({ mode: open }); // 组件结构与样式 shadow.innerHTML style .btn { padding: 8px 16px; border: none; border-radius: 4px; background: #1677ff; color: #fff; cursor: pointer; } /style button classbtn slot/slot /button ; } // 元素被插入到 DOM 时触发 connectedCallback() { console.log(自定义按钮已挂载到页面); } // 元素从 DOM 移除时触发 disconnectedCallback() { console.log(自定义按钮已从页面卸载); } } // 注册自定义标签标签名必须包含横杠 customElements.define(custom-button, CustomButton);注册后即可直接在 HTML 中像原生标签一样使用custom-button确认提交/custom-button二、核心生命周期钩子自定义元素提供了标准化的生命周期钩子用于管控组件不同阶段的逻辑生命周期方法触发时机典型用途constructor()元素实例创建时初始化状态、挂载 Shadow DOM、绑定内部事件connectedCallback()元素被插入到 DOM 文档时请求数据、添加全局监听、初始化第三方依赖disconnectedCallback()元素从 DOM 文档移除时清理定时器、移除全局监听、销毁资源attributeChangedCallback(name, oldVal, newVal)监听的属性发生变化时响应属性变化同步更新组件状态三、核心特点原生级支持W3C 标准浏览器原生实现无需引入任何框架或依赖库。语义化标签自定义标签具备业务语义提升 HTML 源码的可读性与可维护性。跨技术栈复用定义后可在任意前端框架、任意页面中直接使用兼容所有技术体系。标准化生命周期统一的生命周期钩子组件逻辑管控清晰规范。四、典型应用场景基础 UI 组件库按钮、弹窗、表单控件等通用基础组件实现跨框架复用。微前端场景不同技术栈项目之间的组件共享与嵌入避免重复开发。第三方嵌入组件提供给外部页面嵌入的小组件样式隔离无冲突。业务模块封装将复杂业务模块封装为独立标签降低系统耦合度。