]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(custom-element): preserve appContext during update (#12455)
authoredison <daiwei521@126.com>
Tue, 20 May 2025 00:34:36 +0000 (08:34 +0800)
committerGitHub <noreply@github.com>
Tue, 20 May 2025 00:34:36 +0000 (08:34 +0800)
close #12453

packages/runtime-dom/__tests__/customElement.spec.ts
packages/runtime-dom/src/apiCustomElement.ts

index 943dfdc51f7e7cab5d9c9ecca1921cce314f139c..907b299b824fdc25b296a33d0c9f32642d71d052 100644 (file)
@@ -1425,6 +1425,41 @@ describe('defineCustomElement', () => {
 
       expect(e.shadowRoot?.innerHTML).toBe('<div>app-injected</div>')
     })
+
+    test('with hmr reload', async () => {
+      const __hmrId = '__hmrWithApp'
+      const def = defineComponent({
+        __hmrId,
+        setup() {
+          const msg = inject('msg')
+          return { msg }
+        },
+        render(this: any) {
+          return h('div', [h('span', this.msg), h('span', this.$foo)])
+        },
+      })
+      const E = defineCustomElement(def, {
+        configureApp(app) {
+          app.provide('msg', 'app-injected')
+          app.config.globalProperties.$foo = 'foo'
+        },
+      })
+      customElements.define('my-element-with-app-hmr', E)
+
+      container.innerHTML = `<my-element-with-app-hmr></my-element-with-app-hmr>`
+      const el = container.childNodes[0] as VueElement
+      expect(el.shadowRoot?.innerHTML).toBe(
+        `<div><span>app-injected</span><span>foo</span></div>`,
+      )
+
+      // hmr
+      __VUE_HMR_RUNTIME__.reload(__hmrId, def as any)
+
+      await nextTick()
+      expect(el.shadowRoot?.innerHTML).toBe(
+        `<div><span>app-injected</span><span>foo</span></div>`,
+      )
+    })
   })
 
   // #9885
index cd21d0d1ce13b97d7347631127bab1350f240c20..f07246630904495752e6eb0beaa644b286722246 100644 (file)
@@ -533,7 +533,9 @@ export class VueElement
   }
 
   private _update() {
-    render(this._createVNode(), this._root)
+    const vnode = this._createVNode()
+    if (this._app) vnode.appContext = this._app._context
+    render(vnode, this._root)
   }
 
   private _createVNode(): VNode<any, any> {