自定义元素命名必须含连字符,如my-button;constructor中仅允许super()和attachshadow(),dom操作须延至connectedcallback;样式需注入shadow dom;attributechangedcallback不触发初始属性,需在connectedcallback中手动同步。

自定义元素命名必须含连字符,否则 customElements.define() 直接报错
浏览器靠连字符(-)区分原生标签和自定义标签。写成 mybutton 或 MyButton 都会触发 Failed to execute 'define' on 'CustomElementRegistry': The name "mybutton" is not a valid custom element name。
-
my-button✅ 合法:小写 + 连字符 + 非保留名 -
my_button❌ 不合法:下划线不被识别 -
div、button、slot、html❌ 所有原生标签名及全局语义名均禁止注册 -
x-button✅ 可用,但建议用语义化名称如date-picker、nav-menu
constructor 里只能调 super() 和 attachShadow(),DOM 操作一律延后
很多人在 constructor 里直接写 this.innerHTML = '' 或读 this.getAttribute('label'),结果属性读不到、模板不渲染、甚至报 NotSupportedError: Failed to execute 'attachShadow'。
- 允许做的事:调
super()、执行this.attachShadow({ mode: 'open' })、绑定事件监听器、初始化私有字段(如this._value = null) - 禁止做的事:访问
this.innerHTML、调this.querySelector()、读写任何属性(this.getAttribute/this.setAttribute)、操作子节点 - 所有 DOM 渲染和属性读取,必须等到
connectedCallback触发后才安全
样式不生效?不是没写对,是没注入到 Shadow DOM 里
写了 this.attachShadow({ mode: 'open' }) 却发现字体、颜色、间距全丢了——因为 Shadow DOM 天然隔离样式,外部 CSS 不穿透,内部样式也不漏出。
- 必须显式把样式注入到 shadow root:用
shadowRoot.innerHTML = '<style>...</style>...',或动态创建style元素并appendChild - 想让外部控制尺寸或主题色?用 CSS 自定义属性:
:host { display: inline-block; }控制宿主自身,:host([size="large"]) { font-size: 1.2em; }响应属性变化 - 别指望
<style>body { color: red }</style>影响页面 ——body根本不在 shadow 内,且该样式只作用于 shadow 内部
attributeChangedCallback 不处理初始值,HTML 中写的属性要手动同步
注册后首次渲染时,<my-input value="hello"></my-input> 的 value="hello" 不会触发 attributeChangedCallback —— 这是规范行为,不是 bug。
- 必须在
connectedCallback里手动读取初始属性:this.value = this.getAttribute('value') || '' - 同时需配合
static get observedAttributes() { return ['value', 'disabled']; },否则属性变更根本不会进回调 - 若属性是布尔类型(如
disabled),注意getAttribute('disabled')返回""或null,不能直接当布尔值用
connectedCallback 和 attributeChangedCallback 的职责边界:前者负责“第一次挂载时的完整初始化”,后者只管“后续属性变更的增量响应”。混用或漏掉任一环节,组件就卡在半初始化状态。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











