自定义元素命名必须含短横线且全小写,如user-card;DOM操作应在connectedCallback中而非constructor;扩展内置元素需用is属性并继承对应接口;影子根需用:host和::slotted暴露样式接口。

自定义元素命名必须带短横线,否则浏览器直接忽略
浏览器只接受含至少一个短横线(-)的自定义标签名,比如 user-card 合法,usercard 或 UserCard 会被当成 HTMLUnknownElement,不触发任何生命周期回调,也不报错——只是“静默失效”。
- 所有自定义标签名必须小写,且包含且仅包含 ASCII 字母、数字和短横线,开头不能是数字
-
my-component✅,MyComponent❌,component1❌,1component❌ - 命名要语义清晰,避免缩写歧义,比如
prod-card不如product-card
用 connectedCallback 而不是构造函数初始化 DOM
很多人在 constructor 里直接操作 this.innerHTML 或访问 this.children,结果发现属性没生效、子节点为空——因为此时元素还没挂载到 DOM,attributeChangedCallback 也尚未触发,更拿不到 slot 内容。
-
constructor只做最小初始化:调用super()、设置私有属性、绑定 this(如需) - DOM 操作、事件监听、属性读取、影子根创建,全部移到
connectedCallback中 - 若需响应属性变化,记得声明
static observedAttributes = ['prop-name'],否则attributeChangedCallback不会调用
内置元素扩展必须用 is 属性,且继承对应接口
想给 <p> 加字数统计?不能直接写 <word-count>,得用 <p is="word-count">,否则浏览器根本不识别它是你定义的类。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 继承必须严格匹配:扩展
<p>就得继承HTMLParagraphElement,不能只写HTMLElement - 注册时必须传入
{ extends: 'p' },否则customElements.define('word-count', WordCount, { extends: 'p' })会失败 -
is属性值必须全小写,且与define第一个参数一致;HTML 中写成<p is="word-count">,不能写<p is="WordCount">
影子根默认关闭样式穿透,但 :host 和 ::slotted 是关键出口
加了 this.attachShadow({ mode: 'closed' }) 后,外部 CSS 无法影响内部,看起来很干净——但容易忽略:你自己写的样式也得主动暴露接口,否则连基础布局都崩。
立即学习“前端免费学习笔记(深入)”;
-
:host控制自定义元素自身样式(如:host { display: block; }),支持传入 class 或属性选择器::host([size="large"]) { font-size: 1.5em; } -
::slotted(*)匹配所有投射进来的子节点,但只能设有限样式(如 color、font,不能改 display 或 margin) - 若需深度控制插槽内容,得靠属性透传或自定义事件,而不是试图绕过影子边界
observedAttributes 声明和 is 属性的大小写一致性——它们不出错,但会让功能彻底“哑火”,调试时连 console 都没输出。


















