html无组件生命周期,仅customelements.define()注册的自定义元素具备生命周期钩子;connectedcallback在元素插入dom后触发,attributechangedcallback仅响应observedattributes声明的字符串属性变更,disconnectedcallback需安全清理副作用且钩子同步执行。

HTML 本身没有组件生命周期概念,customElements.define() 注册的自定义元素才具备可监听的生命周期钩子——这是最常被误解的前提。
为什么直接写 <my-component></my-component> 不会触发 connectedCallback
浏览器只在元素被正式插入 DOM 后才调用生命周期钩子。常见错误是:先创建元素、再注册类,或注册后未实际挂载。
- 注册必须在元素使用前完成(推荐放在
<script></script>标签顶部或模块入口) -
document.createElement('my-component')创建后,需显式appendChild()或insertAdjacentElement()才触发connectedCallback - 若元素通过
innerHTML插入,且类尚未注册,浏览器会当作普通未知标签处理,钩子永不执行
attributeChangedCallback 的触发条件和参数陷阱
这个钩子只响应 observedAttributes 数组中声明的属性变更,且仅对字符串值敏感——布尔属性、数字、对象都不会自动触发。
- 必须静态定义
static get observedAttributes() { return ['disabled', 'count']; } - 属性值变更必须通过
el.setAttribute('count', '5')或el.count = 5(后者仅当属性有 setter 且同步调用setAttribute时才有效) -
attributeChangedCallback(attrName, oldValue, newValue)中oldValue和newValue永远是字符串,哪怕你传的是数字或null - 首次初始化时(如 HTML 中写
<my-component count="10"></my-component>),钩子也会触发,此时oldValue === null
如何安全地在 disconnectedCallback 中清理副作用
这个钩子不保证一定被调用(比如页面卸载时可能跳过),也不能阻止元素被移除——它只是“通知你:这元素刚从 DOM 里消失了”。
- 清除定时器用
clearTimeout(this._timerId),但需确保this._timerId已定义(避免undefined传给clearTimeout) - 移除事件监听必须用与
addEventListener完全相同的函数引用,建议用绑定方法或箭头函数存为实例属性 - 避免在此处操作 DOM(如
this.remove()),因为元素已脱离文档流,操作无效且可能报错 - 若组件内使用了
IntersectionObserver或ResizeObserver,务必在此处.disconnect()
真正容易被忽略的点是:生命周期钩子都是同步执行的,无法 await;如果需要异步初始化(比如 fetch 数据),必须在 connectedCallback 内手动处理状态标记,防止重复请求或竞态问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











