From 6a3e771dce7127fc8c749989aafa6f7c69d87efa Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 8 May 2025 17:13:54 +0800 Subject: [PATCH] test: add test --- packages/runtime-core/src/renderer.ts | 4 +- .../__tests__/customElement.spec.ts | 98 ++++++++++++++++++- packages/runtime-dom/src/apiCustomElement.ts | 8 +- 3 files changed, 101 insertions(+), 9 deletions(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index e77f624c4f..d75efb890c 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -966,9 +966,7 @@ function baseCreateRenderer( !isSameVNodeType(oldVNode, newVNode) || // - In the case of a component, it could contain anything. oldVNode.shapeFlag & (ShapeFlags.COMPONENT | ShapeFlags.TELEPORT)) - ? oldVNode.el._parentNode && !oldVNode.el.isConnected - ? oldVNode.el._parentNode - : hostParentNode(oldVNode.el)! + ? hostParentNode(oldVNode.el) || oldVNode.el._parentNode : // In other cases, the parent container is not actually used so we // just pass the block element here to avoid a DOM parentNode call. fallbackContainer diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index fa14f6d48f..85f1d0820a 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -9,6 +9,8 @@ import { createCommentVNode, createElementBlock, createElementVNode, + createSlots, + createTextVNode, defineAsyncComponent, defineComponent, defineCustomElement, @@ -1138,8 +1140,8 @@ describe('defineCustomElement', () => { app.unmount() }) - //#13206 - test('should update slotted children correctly w/ shadowRoot false', async () => { + // #13206 + test('update slotted v-if nodes w/ shadowRoot false', async () => { const E = defineCustomElement( defineComponent({ props: { @@ -1148,7 +1150,7 @@ describe('defineCustomElement', () => { render() { return this.isShown ? h('div', { key: 0 }, [renderSlot(this.$slots, 'default')]) - : null + : createCommentVNode('v-if') }, }), { shadowRoot: false }, @@ -1202,7 +1204,7 @@ describe('defineCustomElement', () => { const app = createApp(App) app.mount(container) expect(container.innerHTML).toBe( - ``, + ``, ) click() @@ -1214,7 +1216,7 @@ describe('defineCustomElement', () => { click() await nextTick() expect(container.innerHTML).toBe( - ``, + ``, ) click() @@ -1223,6 +1225,92 @@ describe('defineCustomElement', () => { `
true
hi
`, ) }) + + // #13234 + test('switch between slotted and fallback nodes w/ shadowRoot false', async () => { + const E = defineCustomElement( + defineComponent({ + render() { + return renderSlot(this.$slots, 'foo', {}, () => [ + createTextVNode('fallback'), + ]) + }, + }), + { shadowRoot: false }, + ) + customElements.define('ce-with-fallback-shadow-root-false', E) + + const Comp = defineComponent({ + render() { + return ( + openBlock(), + createElementBlock('ce-with-fallback-shadow-root-false', null, [ + this.$slots.foo + ? (openBlock(), + createElementBlock('div', { key: 0, slot: 'foo' }, [ + renderSlot(this.$slots, 'foo'), + ])) + : createCommentVNode('v-if', true), + renderSlot(this.$slots, 'default'), + ]) + ) + }, + }) + + const isShown = ref(false) + const App = defineComponent({ + components: { Comp }, + render() { + return ( + openBlock(), + createBlock( + Comp, + null, + createSlots( + { _: 2 /* DYNAMIC */ } as any, + [ + isShown.value + ? { + name: 'foo', + fn: withCtx(() => [createTextVNode('foo')]), + key: '0', + } + : undefined, + ] as any, + ), + 1024 /* DYNAMIC_SLOTS */, + ) + ) + }, + }) + + const container = document.createElement('div') + document.body.appendChild(container) + + const app = createApp(App) + app.mount(container) + expect(container.innerHTML).toBe( + `` + + `fallback` + + ``, + ) + + isShown.value = true + await nextTick() + expect(container.innerHTML).toBe( + `` + + `
foo
` + + `
`, + ) + + isShown.value = false + await nextTick() + expect(container.innerHTML).toBe( + `` + + `fallback` + + ``, + ) + }) }) describe('helpers', () => { diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 41d4dc5030..c5f3c9e341 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -337,6 +337,9 @@ export class VueElement this._app && this._app.unmount() if (this._instance) this._instance.ce = undefined this._app = this._instance = null + this._slots = undefined + this._slotFallbacks = undefined + this._slotAnchors = undefined } }) } @@ -692,7 +695,10 @@ export class VueElement for (let i = 0; i < prevNodes.length; i++) { const prevNode = prevNodes[i] const newNode = newNodes[i] - if (isComment(prevNode, 'v-if') || isComment(newNode, 'v-if')) { + if ( + prevNode !== newNode && + (isComment(prevNode, 'v-if') || isComment(newNode, 'v-if')) + ) { Object.keys(this._slots!).forEach(name => { const slotNodes = this._slots![name] if (slotNodes) { -- 2.47.2