diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index dd087ad279d..c45aaa0081d 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -337,6 +337,52 @@ describe('defineCustomElement', () => { await nextTick() expect(consumer.shadowRoot!.innerHTML).toBe(`
changed!
`) }) + + test('inherited from ancestors', async () => { + const fooA = ref('FooA!') + const fooB = ref('FooB!') + const ProviderA = defineCustomElement({ + provide: { + fooA + }, + render() { + return h('provider-b') + } + }) + const ProviderB = defineCustomElement({ + provide: { + fooB + }, + render() { + return h('my-multi-consumer') + } + }) + + const Consumer = defineCustomElement({ + setup() { + const fooA = inject('fooA')! + const fooB = inject('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 = `` + const providerA = container.childNodes[0] as VueElement + const providerB = providerA.shadowRoot!.childNodes[0] as VueElement + const consumer = providerB.shadowRoot!.childNodes[0] as VueElement + + expect(consumer.shadowRoot!.innerHTML).toBe(`
FooA! FooB!
`) + + fooA.value = 'changedA!' + fooB.value = 'changedB!' + await nextTick() + expect(consumer.shadowRoot!.innerHTML).toBe( + `
changedA! changedB!
` + ) + }) }) describe('styles', () => { diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 5108e3bdfbe..5bd81345a45 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -368,6 +368,7 @@ export class VueElement extends BaseClass { ) { if (parent instanceof VueElement) { instance.parent = parent._instance + instance.provides = parent._instance!.provides break } }