From: daiwei Date: Tue, 28 Oct 2025 03:52:06 +0000 (+0800) Subject: wip: save X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7e29657e3074542665445f393d66bf0eb26610c1;p=thirdparty%2Fvuejs%2Fcore.git wip: save --- diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index c1132fb660..ede0987154 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -488,6 +488,8 @@ export abstract class VueElementBase< dispatch(hyphenate(event), args) } } + + this._setParent() } private _resolveProps(def: Def): void { @@ -762,7 +764,6 @@ export class VueElement extends VueElementBase< vnode.ce = instance => { this._instance = instance this._processInstance() - this._setParent() } } return vnode diff --git a/packages/runtime-vapor/__tests__/customElement.spec.ts b/packages/runtime-vapor/__tests__/customElement.spec.ts index 0c4fca6018..6a724ba27f 100644 --- a/packages/runtime-vapor/__tests__/customElement.spec.ts +++ b/packages/runtime-vapor/__tests__/customElement.spec.ts @@ -2,7 +2,10 @@ import type { VaporElement } from '../src/apiDefineVaporCustomElement' import { type HMRRuntime, + type Ref, + inject, nextTick, + provide, ref, toDisplayString, } from '@vue/runtime-dom' @@ -808,200 +811,208 @@ describe('defineVaporCustomElement', () => { }) }) - // describe('provide/inject', () => { - // const Consumer = defineVaporCustomElement({ - // setup() { - // const foo = inject('foo')! - // return () => h('div', foo.value) - // }, - // }) - // customElements.define('my-consumer', Consumer) - - // test('over nested usage', async () => { - // const foo = ref('injected!') - // const Provider = defineVaporCustomElement({ - // provide: { - // foo, - // }, - // render() { - // return h('my-consumer') - // }, - // }) - // customElements.define('my-provider', Provider) - // container.innerHTML = `` - // const provider = container.childNodes[0] as VaporElement - // const consumer = provider.shadowRoot!.childNodes[0] as VaporElement - - // expect(consumer.shadowRoot!.innerHTML).toBe(`
injected!
`) - - // foo.value = 'changed!' - // await nextTick() - // 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) + describe.todo('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))) + return n0 + }, + }) + customElements.define('my-consumer', Consumer) + + 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') + }, + }) + customElements.define('my-provider', Provider) + container.innerHTML = `` + const provider = container.childNodes[0] as VaporElement + const consumer = provider.shadowRoot!.childNodes[0] as VaporElement - // container.innerHTML = `` - // const provider = container.childNodes[0] - // const consumer = provider.childNodes[0] as VaporElement - // expect(consumer.shadowRoot!.innerHTML).toBe(`
injected!
`) + 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('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) - // const Consumer = defineVaporCustomElement({ - // setup() { - // const fooA = inject('fooA')! - // const fooB = inject('fooB')! - // return () => h('div', `${fooA.value} ${fooB.value}`) - // }, - // }) + // container.innerHTML = `` + // const provider = container.childNodes[0] + // const consumer = provider.childNodes[0] as VaporElement + // expect(consumer.shadowRoot!.innerHTML).toBe(`
injected!
`) - // 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 + // foo.value = 'changed!' + // await nextTick() + // expect(consumer.shadowRoot!.innerHTML).toBe(`
changed!
`) + // }) - // expect(consumer.shadowRoot!.innerHTML).toBe(`
FooA! FooB!
`) + // 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') + // }, + // }) - // 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')! + // 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!
`, + // ) + // }) - // // #13212 - // test('inherited from app context within nested elements', async () => { - // const outerValues: (string | undefined)[] = [] - // const innerValues: (string | undefined)[] = [] - // const innerChildValues: (string | undefined)[] = [] + // // #13212 + // 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'), - // ) - // }, - // render() { - // return h('div', [renderSlot(this.$slots, 'default')]) - // }, - // }, - // { - // configureApp(app) { - // app.provide('shared', 'shared') - // app.provide('outer', 'outer') - // }, - // }, - // ) - - // const Inner = defineVaporCustomElement( - // { - // setup() { - // // ensure values are not self-injected - // provide('inner', 'inner-child') + // 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') + // }, + // }, + // ) - // 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') - // }, - // }, - // ) + // 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') + // }, + // }, + // ) - // const InnerChild = defineVaporCustomElement({ - // setup() { - // innerChildValues.push( - // inject('shared'), - // inject('outer'), - // inject('inner'), - // ) - // }, - // render() { - // return h('div') - // }, - // }) + // const InnerChild = defineVaporCustomElement({ + // setup() { + // innerChildValues.push( + // inject('shared'), + // inject('outer'), + // inject('inner'), + // ) + // }, + // render() { + // return h('div') + // }, + // }) - // customElements.define('provide-from-app-outer', Outer) - // customElements.define('provide-from-app-inner', Inner) - // customElements.define('provide-from-app-inner-child', InnerChild) + // customElements.define('provide-from-app-outer', Outer) + // customElements.define('provide-from-app-inner', Inner) + // customElements.define('provide-from-app-inner-child', InnerChild) - // container.innerHTML = - // '' + - // '' + - // '' + - // '' + - // '' + // container.innerHTML = + // '' + + // '' + + // '' + + // '' + + // '' - // const outer = container.childNodes[0] as VaporElement - // expect(outer.shadowRoot!.innerHTML).toBe('
') + // 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', - // ]) - // }) - // }) + // 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', () => { // function assertStyles(el: VaporElement, css: string[]) { diff --git a/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts b/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts index b9ebf35db3..9f8aba47e6 100644 --- a/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts +++ b/packages/runtime-vapor/src/apiDefineVaporCustomElement.ts @@ -87,7 +87,7 @@ export class VaporElement extends VueElementBase< this._def.configureApp(this._app) } - this._app._ceComponent = this._createComponent() + this._createComponent() this._app!.mount(this._root) } @@ -118,21 +118,20 @@ export class VaporElement extends VueElementBase< } else { this._app!.unmount() } + if (this._instance && this._instance.ce) { + this._instance.ce = undefined + } this._app = this._instance = null } private _createComponent() { this._def.ce = instance => { - this._instance = instance + this._app!._ceComponent = this._instance = instance if (!this.shadowRoot) { - ;(instance.m || (instance.m = [])).push(this._renderSlots.bind(this)) - ;(instance.u || (instance.u = [])).push(this._renderSlots.bind(this)) + this._instance!.m = this._instance!.u = [this._renderSlots.bind(this)] } this._processInstance() - this._setParent() } - - this._instance = createComponent(this._def, this._props) - return this._instance + createComponent(this._def, this._props) } }