customelements.define()是注册自定义元素的唯一入口;类名必须含连字符(如my-button)以满足规范;attributechangedcallback仅响应observedattributes声明且通过setattribute等触发的属性变更;shadow dom需用slot透传内容、dispatchevent通知外部;组件行为一致性需在生命周期钩子间权衡。

customElements.define() 是唯一能注册自定义标签的入口,不调用它,类写得再完整也进不了 DOM。
为什么 class MyButton extends HTMLElement 必须带连字符?
浏览器靠连字符(如 my-button、user-card)识别合法的自定义标签名。用 mybutton 或 MyButton 会直接报错:Failed to execute 'define' on 'CustomElementRegistry': The name "mybutton" is not a valid custom element name。
- 连字符是强制语法要求,不是风格建议
- 不能以数字开头,不能包含大写字母或下划线
- 已注册的同名标签不可覆盖,需刷新页面或先
customElements.get('my-button')判断是否存在
attributeChangedCallback 不触发?检查这三处
这个钩子只响应 observedAttributes 显式声明的属性,且仅对通过 setAttribute、removeAttribute 或 HTML 属性变更生效,不响应 JS 对 this.xxx = value 的赋值。
- 必须在类中静态定义
static get observedAttributes() { return ['label', 'disabled']; } - HTML 中写
<my-button label="提交"></my-button>会触发;但el.label = '提交'不会 - 首次初始化时(即从 HTML 解析阶段)的属性值不会进该回调,要用
constructor或connectedCallback补读
Shadow DOM 里怎么响应外部事件?别漏掉 slot 和 dispatchEvent
Shadow DOM 天然隔离样式和事件流,外部点击进不去内部按钮,内部按钮点击也传不到外层——除非你主动透传或暴露接口。
- 用
<slot></slot>让用户把内容“塞进来”,比如<my-modal><h2 slot="title">提示</h2> <p slot="body">确定删除?</p></my-modal> - 内部操作要通知外部,得手动
this.dispatchEvent(new CustomEvent('confirm', { detail: { ok: true } })) - 不要在
shadowRoot上监听click后直接调this.click——那只是触发自己身上的原生事件,外部没监听就等于白发
constructor、connectedCallback、attributeChangedCallback 之间做取舍,没有银弹,只有权衡。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











