web components 的核心价值在于跨技术栈复用和强封装,适用于多框架共用ui基础块、微前端子应用隔离等场景;单一框架项目中硬套 custom elements 反而丧失响应式、状态管理等优势。

Web Components 不是“要不要用”的问题,而是“在哪些场景下必须用、哪些场景下不该硬上”的问题。它最核心的价值,是解决跨技术栈复用和强封装需求——不是所有组件都适合写成 customElements.define。
多框架共用组件时,Custom Elements 是唯一靠谱的选择
当你有按钮、表单控件、数据表格这类 UI 基础块,要同时塞进 Vue 项目、React 项目、甚至纯静态 HTML 页面里,Custom Elements 就成了事实标准:
- React/Vue 渲染器对
<my-button></my-button>这种标签不做特殊处理,直接当原生元素挂载,connectedCallback会正常触发 - 不需要额外适配层(比如 React 的
createRoot或 Vue 的defineCustomElement),开箱即用 - 样式隔离靠
Shadow DOM,避免和宿主页面的 CSS 冲突,尤其适合嵌入第三方系统(如 CMS 插件、SaaS 后台嵌入) - 注意:如果组件需要 SSR,
Shadow DOM在服务端无法渲染,得搭配 Lit + SSR 工具链,纯原生 Custom Elements 不支持
微前端架构里,自定义元素天然适配子应用边界
微前端中各子应用常由不同团队用不同技术栈开发,而 Custom Elements 提供了统一的 DOM 接口层:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 主应用只负责挂载
<user-profile-widget></user-profile-widget>,不关心它内部是 Vue 还是 Svelte 实现 - 子应用发布时打包成独立 JS 文件,通过
import或script加载,注册后即可使用 - 生命周期可控:
disconnectedCallback是清理定时器、取消 fetch 的关键时机,但要注意它不保证执行(比如用户关 tab),建议配合AbortController - 事件通信走标准 DOM Event,避免框架私有事件总线,
this.dispatchEvent(new CustomEvent('submit', { detail: data }))即可
单一框架项目里,别为了“原生”而放弃框架能力
如果你整个项目就是 Vue 或 React,还硬把所有组件写成 Custom Elements,等于主动放弃框架的核心优势:
- 响应式更新失效:属性变更不会自动重 render,得手动监听
attributeChangedCallback并调this.render() - 状态管理脱节:Vue 的
ref/ React 的useState无法直接绑定到<my-input></my-input>的 property 上,必须用setAttribute模拟 - 开发体验倒退:没有 JSX/模板语法、无热更新、调试困难,
console.log(this)看到的是原生元素实例,不是组件实例 - 性能未必更好:Shadow DOM 的克隆和 diff 成本,有时比框架虚拟 DOM 更高,尤其含大量动态内容时
容易被忽略的兼容性与初始化陷阱
很多问题不是逻辑写错,而是没踩对浏览器的触发节奏:
-
connectedCallback只在首次插入 active DOM 树时执行——document.createElement('my-card')后没appendChild,它永远不触发 -
customElements.define('my-card', MyCard)必须在 HTML 解析前或<my-card></my-card>出现前执行,否则标签被当成未知元素静默忽略 - 自定义标签名必须含短横线:
my-card合法,myCard或my_card直接报错Failed to execute 'define' on 'CustomElementRegistry': The name must contain a dash.' - 继承内置元素(如
extends: 'button')时,必须用is属性写法:<button is="loading-button"></button>,IE 完全不支持,现代项目慎用
真正难的不是写一个能跑的 class MyCard extends HTMLElement,而是判断这个组件是否真的需要脱离框架、承担 Shadow DOM 开销、并接受 attribute-only 的通信约束。多数业务组件,还是交给 Vue/React 更省心;只有那些“必须跨出去”的部分,才值得用 Custom Elements 死磕。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










