]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix: update createComponent call to include app context
authordaiwei <daiwei521@126.com>
Tue, 28 Oct 2025 06:15:19 +0000 (14:15 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 28 Oct 2025 06:15:19 +0000 (14:15 +0800)
packages/runtime-vapor/__tests__/customElement.spec.ts
packages/runtime-vapor/src/apiDefineVaporCustomElement.ts

index 6a724ba27fc6d3e879b55cd524529df5450a407d..628e0fa0a43c9914064020bedbdb2713e3958712 100644 (file)
@@ -811,11 +811,10 @@ describe('defineVaporCustomElement', () => {
     })
   })
 
-  describe.todo('provide/inject', () => {
+  describe('provide/inject', () => {
     const Consumer = defineVaporCustomElement({
       setup() {
         const foo = inject<Ref>('foo')!
-        // return () => h('div', foo.value)
         const n0 = template('<div> </div>', true)() as any
         const x0 = txt(n0) as any
         renderEffect(() => setText(x0, toDisplayString(foo.value)))
@@ -827,12 +826,6 @@ describe('defineVaporCustomElement', () => {
     test('over nested usage', async () => {
       const foo = ref('injected!')
       const Provider = defineVaporCustomElement({
-        // provide: {
-        //   foo,
-        // },
-        // render() {
-        //   return h('my-consumer')
-        // },
         setup() {
           provide('foo', foo)
           return createComponentWithFallback('my-consumer')
@@ -850,168 +843,168 @@ describe('defineVaporCustomElement', () => {
       expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
     })
 
-    // test('over slot composition', async () => {
-    //   const foo = ref('injected!')
-    //   const Provider = defineVaporCustomElement({
-    //     provide: {
-    //       foo,
-    //     },
-    //     render() {
-    //       return renderSlot(this.$slots, 'default')
-    //     },
-    //   })
-    //   customElements.define('my-provider-2', Provider)
+    test('over slot composition', async () => {
+      const foo = ref('injected!')
+      const Provider = defineVaporCustomElement({
+        setup() {
+          provide('foo', foo)
+          return createSlot('default', null)
+        },
+      })
+      customElements.define('my-provider-2', Provider)
 
-    //   container.innerHTML = `<my-provider-2><my-consumer></my-consumer><my-provider-2>`
-    //   const provider = container.childNodes[0]
-    //   const consumer = provider.childNodes[0] as VaporElement
-    //   expect(consumer.shadowRoot!.innerHTML).toBe(`<div>injected!</div>`)
+      container.innerHTML = `<my-provider-2><my-consumer></my-consumer><my-provider-2>`
+      const provider = container.childNodes[0]
+      const consumer = provider.childNodes[0] as VaporElement
+      expect(consumer.shadowRoot!.innerHTML).toBe(`<div>injected!</div>`)
 
-    //   foo.value = 'changed!'
-    //   await nextTick()
-    //   expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
-    // })
+      foo.value = 'changed!'
+      await nextTick()
+      expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
+    })
 
-    // test('inherited from ancestors', async () => {
-    //   const fooA = ref('FooA!')
-    //   const fooB = ref('FooB!')
-    //   const ProviderA = defineVaporCustomElement({
-    //     provide: {
-    //       fooA,
-    //     },
-    //     render() {
-    //       return h('provider-b')
-    //     },
-    //   })
-    //   const ProviderB = defineVaporCustomElement({
-    //     provide: {
-    //       fooB,
-    //     },
-    //     render() {
-    //       return h('my-multi-consumer')
-    //     },
-    //   })
+    test('inherited from ancestors', async () => {
+      const fooA = ref('FooA!')
+      const fooB = ref('FooB!')
+      const ProviderA = defineVaporCustomElement({
+        setup() {
+          provide('fooA', fooA)
+          return createComponentWithFallback('provider-b')
+        },
+      })
+      const ProviderB = defineVaporCustomElement({
+        setup() {
+          provide('fooB', fooB)
+          return createComponentWithFallback('my-multi-consumer')
+        },
+      })
 
-    //   const Consumer = defineVaporCustomElement({
-    //     setup() {
-    //       const fooA = inject<Ref>('fooA')!
-    //       const fooB = inject<Ref>('fooB')!
-    //       return () => h('div', `${fooA.value} ${fooB.value}`)
-    //     },
-    //   })
-
-    //   customElements.define('provider-a', ProviderA)
-    //   customElements.define('provider-b', ProviderB)
-    //   customElements.define('my-multi-consumer', Consumer)
-    //   container.innerHTML = `<provider-a><provider-a>`
-    //   const providerA = container.childNodes[0] as VaporElement
-    //   const providerB = providerA.shadowRoot!.childNodes[0] as VaporElement
-    //   const consumer = providerB.shadowRoot!.childNodes[0] as VaporElement
-
-    //   expect(consumer.shadowRoot!.innerHTML).toBe(`<div>FooA! FooB!</div>`)
-
-    //   fooA.value = 'changedA!'
-    //   fooB.value = 'changedB!'
-    //   await nextTick()
-    //   expect(consumer.shadowRoot!.innerHTML).toBe(
-    //     `<div>changedA! changedB!</div>`,
-    //   )
-    // })
+      const Consumer = defineVaporCustomElement({
+        setup() {
+          const fooA = inject<Ref>('fooA')!
+          const fooB = inject<Ref>('fooB')!
+          const n0 = template('<div> </div>', true)() as any
+          const x0 = txt(n0) as any
+          renderEffect(() => setText(x0, `${fooA.value} ${fooB.value}`))
+          return n0
+        },
+      })
 
-    // // #13212
-    // test('inherited from app context within nested elements', async () => {
-    //   const outerValues: (string | undefined)[] = []
-    //   const innerValues: (string | undefined)[] = []
-    //   const innerChildValues: (string | undefined)[] = []
+      customElements.define('provider-a', ProviderA)
+      customElements.define('provider-b', ProviderB)
+      customElements.define('my-multi-consumer', Consumer)
+      container.innerHTML = `<provider-a><provider-a>`
+      const providerA = container.childNodes[0] as VaporElement
+      const providerB = providerA.shadowRoot!.childNodes[0] as VaporElement
+      const consumer = providerB.shadowRoot!.childNodes[0] as VaporElement
 
-    //   const Outer = defineVaporCustomElement(
-    //     {
-    //       setup() {
-    //         outerValues.push(
-    //           inject<string>('shared'),
-    //           inject<string>('outer'),
-    //           inject<string>('inner'),
-    //         )
-    //       },
-    //       render() {
-    //         return h('div', [renderSlot(this.$slots, 'default')])
-    //       },
-    //     },
-    //     {
-    //       configureApp(app) {
-    //         app.provide('shared', 'shared')
-    //         app.provide('outer', 'outer')
-    //       },
-    //     },
-    //   )
+      expect(consumer.shadowRoot!.innerHTML).toBe(`<div>FooA! FooB!</div>`)
 
-    //   const Inner = defineVaporCustomElement(
-    //     {
-    //       setup() {
-    //         // ensure values are not self-injected
-    //         provide('inner', 'inner-child')
-
-    //         innerValues.push(
-    //           inject<string>('shared'),
-    //           inject<string>('outer'),
-    //           inject<string>('inner'),
-    //         )
-    //       },
-    //       render() {
-    //         return h('div', [renderSlot(this.$slots, 'default')])
-    //       },
-    //     },
-    //     {
-    //       configureApp(app) {
-    //         app.provide('outer', 'override-outer')
-    //         app.provide('inner', 'inner')
-    //       },
-    //     },
-    //   )
+      fooA.value = 'changedA!'
+      fooB.value = 'changedB!'
+      await nextTick()
+      expect(consumer.shadowRoot!.innerHTML).toBe(
+        `<div>changedA! changedB!</div>`,
+      )
+    })
 
-    //   const InnerChild = defineVaporCustomElement({
-    //     setup() {
-    //       innerChildValues.push(
-    //         inject<string>('shared'),
-    //         inject<string>('outer'),
-    //         inject<string>('inner'),
-    //       )
-    //     },
-    //     render() {
-    //       return h('div')
-    //     },
-    //   })
+    test('inherited from app context within nested elements', async () => {
+      const outerValues: (string | undefined)[] = []
+      const innerValues: (string | undefined)[] = []
+      const innerChildValues: (string | undefined)[] = []
+
+      const Outer = defineVaporCustomElement(
+        {
+          setup() {
+            outerValues.push(
+              inject<string>('shared'),
+              inject<string>('outer'),
+              inject<string>('inner'),
+            )
+
+            const n0 = template('<div></div>', true)() as any
+            setInsertionState(n0, null)
+            createSlot('default', null)
+            return n0
+          },
+        },
+        {
+          configureApp(app: any) {
+            app.provide('shared', 'shared')
+            app.provide('outer', 'outer')
+          },
+        } as any,
+      )
 
-    //   customElements.define('provide-from-app-outer', Outer)
-    //   customElements.define('provide-from-app-inner', Inner)
-    //   customElements.define('provide-from-app-inner-child', InnerChild)
+      const Inner = defineVaporCustomElement(
+        {
+          setup() {
+            // ensure values are not self-injected
+            provide('inner', 'inner-child')
+
+            innerValues.push(
+              inject<string>('shared'),
+              inject<string>('outer'),
+              inject<string>('inner'),
+            )
+            const n0 = template('<div></div>', true)() as any
+            setInsertionState(n0, null)
+            createSlot('default', null)
+            return n0
+          },
+        },
+        {
+          configureApp(app: any) {
+            app.provide('outer', 'override-outer')
+            app.provide('inner', 'inner')
+          },
+        } as any,
+      )
 
-    //   container.innerHTML =
-    //     '<provide-from-app-outer>' +
-    //     '<provide-from-app-inner>' +
-    //     '<provide-from-app-inner-child></provide-from-app-inner-child>' +
-    //     '</provide-from-app-inner>' +
-    //     '</provide-from-app-outer>'
+      const InnerChild = defineVaporCustomElement({
+        setup() {
+          innerChildValues.push(
+            inject<string>('shared'),
+            inject<string>('outer'),
+            inject<string>('inner'),
+          )
+          const n0 = template('<div></div>', true)() as any
+          return n0
+        },
+      })
 
-    //   const outer = container.childNodes[0] as VaporElement
-    //   expect(outer.shadowRoot!.innerHTML).toBe('<div><slot></slot></div>')
+      customElements.define('provide-from-app-outer', Outer)
+      customElements.define('provide-from-app-inner', Inner)
+      customElements.define('provide-from-app-inner-child', InnerChild)
 
-    //   expect('[Vue warn]: injection "inner" not found.').toHaveBeenWarnedTimes(
-    //     1,
-    //   )
-    //   expect(
-    //     '[Vue warn]: App already provides property with key "outer" inherited from its parent element. ' +
-    //       'It will be overwritten with the new value.',
-    //   ).toHaveBeenWarnedTimes(1)
-
-    //   expect(outerValues).toEqual(['shared', 'outer', undefined])
-    //   expect(innerValues).toEqual(['shared', 'override-outer', 'inner'])
-    //   expect(innerChildValues).toEqual([
-    //     'shared',
-    //     'override-outer',
-    //     'inner-child',
-    //   ])
-    // })
+      container.innerHTML =
+        '<provide-from-app-outer>' +
+        '<provide-from-app-inner>' +
+        '<provide-from-app-inner-child></provide-from-app-inner-child>' +
+        '</provide-from-app-inner>' +
+        '</provide-from-app-outer>'
+
+      const outer = container.childNodes[0] as VaporElement
+      expect(outer.shadowRoot!.innerHTML).toBe(
+        '<div><slot></slot><!--slot--></div>',
+      )
+
+      expect('[Vue warn]: injection "inner" not found.').toHaveBeenWarnedTimes(
+        1,
+      )
+      expect(
+        '[Vue warn]: App already provides property with key "outer" inherited from its parent element. ' +
+          'It will be overwritten with the new value.',
+      ).toHaveBeenWarnedTimes(1)
+
+      expect(outerValues).toEqual(['shared', 'outer', undefined])
+      expect(innerValues).toEqual(['shared', 'override-outer', 'inner'])
+      expect(innerChildValues).toEqual([
+        'shared',
+        'override-outer',
+        'inner-child',
+      ])
+    })
   })
 
   // describe('styles', () => {
index 9f8aba47e666deb3581392b16d533d14df7ae5b8..6cf9b5f67aa84c870a60b98193a4ffffce41abfe 100644 (file)
@@ -132,6 +132,14 @@ export class VaporElement extends VueElementBase<
       }
       this._processInstance()
     }
-    createComponent(this._def, this._props)
+
+    createComponent(
+      this._def,
+      this._props,
+      undefined,
+      undefined,
+      undefined,
+      this._app!._context,
+    )
   }
 }