From: daiwei Date: Tue, 28 Oct 2025 06:15:19 +0000 (+0800) Subject: fix: update createComponent call to include app context X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9fa0d6310fbd58e45f80a1009cde16fb38d0655b;p=thirdparty%2Fvuejs%2Fcore.git fix: update createComponent call to include app context --- diff --git a/packages/runtime-vapor/__tests__/customElement.spec.ts b/packages/runtime-vapor/__tests__/customElement.spec.ts index 6a724ba27f..628e0fa0a4 100644 --- a/packages/runtime-vapor/__tests__/customElement.spec.ts +++ b/packages/runtime-vapor/__tests__/customElement.spec.ts @@ -811,11 +811,10 @@ describe('defineVaporCustomElement', () => { }) }) - describe.todo('provide/inject', () => { + describe('provide/inject', () => { const Consumer = defineVaporCustomElement({ setup() { const foo = inject('foo')! - // return () => h('div', foo.value) const n0 = template('
', 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(`
changed!
`) }) - // 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 = `` - // const provider = container.childNodes[0] - // const consumer = provider.childNodes[0] as VaporElement - // expect(consumer.shadowRoot!.innerHTML).toBe(`
injected!
`) + container.innerHTML = `` + const provider = container.childNodes[0] + const consumer = provider.childNodes[0] as VaporElement + expect(consumer.shadowRoot!.innerHTML).toBe(`
injected!
`) - // foo.value = 'changed!' - // await nextTick() - // expect(consumer.shadowRoot!.innerHTML).toBe(`
changed!
`) - // }) + foo.value = 'changed!' + await nextTick() + expect(consumer.shadowRoot!.innerHTML).toBe(`
changed!
`) + }) - // 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('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 VaporElement - // const providerB = providerA.shadowRoot!.childNodes[0] as VaporElement - // const consumer = providerB.shadowRoot!.childNodes[0] as VaporElement - - // expect(consumer.shadowRoot!.innerHTML).toBe(`
FooA! FooB!
`) - - // fooA.value = 'changedA!' - // fooB.value = 'changedB!' - // await nextTick() - // expect(consumer.shadowRoot!.innerHTML).toBe( - // `
changedA! changedB!
`, - // ) - // }) + const Consumer = defineVaporCustomElement({ + setup() { + const fooA = inject('fooA')! + const fooB = inject('fooB')! + const n0 = template('
', 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 = `` + 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('shared'), - // inject('outer'), - // inject('inner'), - // ) - // }, - // render() { - // return h('div', [renderSlot(this.$slots, 'default')]) - // }, - // }, - // { - // configureApp(app) { - // app.provide('shared', 'shared') - // app.provide('outer', 'outer') - // }, - // }, - // ) + expect(consumer.shadowRoot!.innerHTML).toBe(`
FooA! FooB!
`) - // const Inner = defineVaporCustomElement( - // { - // setup() { - // // ensure values are not self-injected - // provide('inner', 'inner-child') - - // innerValues.push( - // inject('shared'), - // inject('outer'), - // inject('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( + `
changedA! changedB!
`, + ) + }) - // const InnerChild = defineVaporCustomElement({ - // setup() { - // innerChildValues.push( - // inject('shared'), - // inject('outer'), - // inject('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('shared'), + inject('outer'), + inject('inner'), + ) + + const n0 = template('
', 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('shared'), + inject('outer'), + inject('inner'), + ) + const n0 = template('
', 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 = - // '' + - // '' + - // '' + - // '' + - // '' + const InnerChild = defineVaporCustomElement({ + setup() { + innerChildValues.push( + inject('shared'), + inject('outer'), + inject('inner'), + ) + const n0 = template('
', true)() as any + return n0 + }, + }) - // const outer = container.childNodes[0] as VaporElement - // expect(outer.shadowRoot!.innerHTML).toBe('
') + 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 = + '' + + '' + + '' + + '' + + '' + + const outer = container.childNodes[0] as VaporElement + expect(outer.shadowRoot!.innerHTML).toBe( + '
', + ) + + 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', () => { diff --git a/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts b/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts index 9f8aba47e6..6cf9b5f67a 100644 --- a/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts +++ b/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts @@ -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, + ) } }