Vue 异步自定义元素移除后仍挂载,读取 provides 报错
异步子元素断开后才完成定义加载,Vue 3.5.43 仍可能挂载并读取已销毁父上下文。3.5.44 加入连接状态守卫,再连接仍走正常挂载。
异步自定义元素尚未加载完成就被移除,稍后却报 Cannot read properties of null (reading 'provides');重新插回后,里面的后代元素还可能保持空白。如果错误恰好发生在元素自己的组件定义加载完成时,应检查它是否在断开连接期间仍尝试挂载。
Vue 3.5.43 有这条明确表现,正式 3.5.44 已包含跳过“加载期间被移除的异步自定义元素”的挂载修正。这里针对元素自己的定义加载,不等同于子元素等待父元素定义的另一条时序。
加载结束时,父实例可能已经销毁
具体结构是 Vue 自定义父元素包含一个异步子元素,子元素里还有后代自定义元素。整个块在子定义尚未完成时离开 DOM,父实例随后卸载;子定义完成后,旧路径仍试图挂载子实例并继承父级上下文,于是尝试从空的父实例读取 provides。
没有 Vue 父元素时,这条路径也可能表现为元素已经断开,mounted 却仍执行。重新连接后显示恢复了一部分,不代表后代实例或上下文已经正确建立。
保留元素连接、断开、定义加载完成和再次连接的实际顺序,检查异常是否发生在断开窗口。如果元素一直连接着,或 provides 错误来自普通组件的其他代码,应继续检查对应实例生命周期,不能仅按报错属性名套用修复。
让定义解析与连接状态配合
项目允许时采用 Vue 3.5.44,并让自定义元素构建和页面消费端使用兼容的 Vue 依赖。修复针对的是初次定义加载完成后的挂载条件,不是取消异步加载;元素以后真正重新连接,仍应按正常连接流程挂载。
不要修改 provides 为一个空对象来消除异常。那可能让实例继续运行,却丢失原来应该继承的上下文。也不要在断开期间手工调用内部挂载函数,或伪造 isConnected;这些做法会绕开元素实际的连接状态。
应用自行编排加载与移除时,可以检查是否有已失效的操作仍持有元素,并让后续处理确认它仍属于当前页面。这样的应用侧生命周期管理不能代替框架修复,也不应为了等待网络加载完成而永久阻止用户离开页面。
验收覆盖“加载未完成时移除且不再插回”和“移除、加载完成、再连接”两种情况。前者不应在断开期间执行不合适的挂载或抛出 provides 异常;后者应让子元素与后代内容正常出现,原有注入上下文和卸载清理仍有效。其他重连问题需要另查,不能由这次局部修正一并保证。


