connectedcallback 是唯一能安全操作 dom 的时机,它仅在元素真正插入主文档时触发,此时 this.shadowroot 已存在,可安全写入内容、绑定事件、发起 fetch;需加 _initialized 标志防重复执行。

connectedCallback 是唯一能安全操作 DOM 的时机
它只在元素真正插入主文档 DOM 时触发,不是定义完就跑,也不是 new 出来就调。很多开发者误以为写完 <my-card></my-card> 就会进这个钩子,结果发现 fetch 没发、事件没绑、this.shadowRoot 是 null——根本原因是元素还没挂载。
- 必须等
parent.appendChild(el)执行后才触发;用innerHTML = '<my-card></my-card>'不会触发,浏览器走字符串解析路径,绕过生命周期 -
this.shadowRoot此时已存在,可安全写入内容、绑定事件、调用fetch() - 要防重复执行:加私有标志位
this._initialized = true,并在钩子里检查;否则元素被移出又重新插入(比如列表滚动复用),会重复拉数据或重绑监听器 - 子元素可能尚未解析完成,别依赖
this.querySelector('button')查找还未升级的自定义子组件
attributeChangedCallback 必须显式声明 observedAttributes
这个钩子不会自动监听任意属性,哪怕你写了方法,没声明就等于没写。常见错误是 HTML 写了 <my-input value="42"></my-input>,JS 里却监听 'val' 或 'Value',结果回调从不执行。
- 静态 getter 必须返回字符串数组:
static get observedAttributes() { return ['value', 'disabled', 'data-id']; } - 属性名严格匹配 HTML 写法:
data-user-id→ 监听'data-user-id',不能写成'userId'或'dataUserId' -
oldValue和newValue都是字符串,需手动转换类型,例如:const val = Number(newValue); - 首次渲染(如 SSR 输出)不触发该回调,
oldValue为null,初始化逻辑仍得在connectedCallback中补一手:this.getAttribute('value') - 直接赋值
el.value = 'abc'是 property 操作,不触发;只有el.setAttribute('value', 'abc')或 HTML 解析才进回调
disconnectedCallback 清理逻辑必须带 guard 判断
它是清理定时器、事件监听、AbortController 的最后机会,但浏览器不保证一定执行——关页、崩溃、后台冻结都会跳过它。所以不能只靠它,也不能在里面做关键持久化。
- 所有异步操作建议配
AbortSignal,在connectedCallback中创建new AbortController()并存到this._abort,在disconnectedCallback中调this._abort?.abort() - 清理前加判断:
if (this._timer) clearInterval(this._timer);,避免重复调用或访问已销毁引用 - 全局监听(如
window.addEventListener('resize', ...))必须在这里移除,但也要在connectedCallback中先removeEventListener再addEventListener,防止多次挂载导致监听器堆积 - 不要写
localStorage.setItem(...)—— 状态变更时应实时存,或用beforeunload补兜底
constructor 里只能做轻量初始化
这是最容易出错的地方:很多人在 constructor 里直接操作 this.shadowRoot 或调 fetch(),结果报 TypeError: Cannot set property 'innerHTML' of null。
-
this.shadowRoot此时为null,但可以调this.attachShadow({ mode: 'open' })创建它,只是别往里写内容 - 只允许做字段初始化、方法绑定、私有变量声明,例如:
this._timer = null;、this._abort = null;、this.handleClick = this.handleClick.bind(this); - 禁止异步逻辑:
setTimeout、Promise、async/await全都不行,因为元素仍处于未挂载状态,DOM 不可用 - 不能调
document.querySelector或任何依赖 DOM 就绪的操作,连this.querySelector都会返回null
disconnectedCallback 的不可靠性,以及 observedAttributes 声明遗漏——这两个点一旦漏掉,问题往往静默失效,调试时很难定位。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











