diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 4a9e0fac2b6..1ff141db8ab 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -1677,6 +1677,35 @@ describe('SSR hydration', () => {
expect(`mismatch`).not.toHaveBeenWarned()
})
+ // #13394
+ test('transition appear work with empty content', async () => {
+ const show = ref(true)
+ const { vnode, container } = mountWithHydration(
+ ``,
+ function (this: any) {
+ return h(
+ Transition,
+ { appear: true },
+ {
+ default: () =>
+ show.value
+ ? renderSlot(this.$slots, 'default')
+ : createTextVNode('foo'),
+ },
+ )
+ },
+ )
+
+ // empty slot render as a comment node
+ expect(container.firstChild!.nodeType).toBe(Node.COMMENT_NODE)
+ expect(vnode.el).toBe(container.firstChild)
+ expect(`mismatch`).not.toHaveBeenWarned()
+
+ show.value = false
+ await nextTick()
+ expect(container.innerHTML).toBe('foo')
+ })
+
test('transition appear with v-if', () => {
const show = false
const { vnode, container } = mountWithHydration(
diff --git a/packages/server-renderer/__tests__/ssrSlot.spec.ts b/packages/server-renderer/__tests__/ssrSlot.spec.ts
index 4cc7fd97ef2..214e6ee840b 100644
--- a/packages/server-renderer/__tests__/ssrSlot.spec.ts
+++ b/packages/server-renderer/__tests__/ssrSlot.spec.ts
@@ -111,26 +111,106 @@ describe('ssr: slot', () => {
})
test('transition slot', async () => {
+ const ReusableTransition = {
+ template: ``,
+ }
+
+ const ReusableTransitionWithAppear = {
+ template: ``,
+ }
+
expect(
await renderToString(
createApp({
components: {
- one: {
- template: ``,
- },
+ one: ReusableTransition,
},
template: `foo
`,
}),
),
).toBe(``)
+ expect(await renderToString(createApp(ReusableTransition))).toBe(``)
+
+ expect(await renderToString(createApp(ReusableTransitionWithAppear))).toBe(
+ ``,
+ )
+
expect(
await renderToString(
createApp({
components: {
- one: {
- template: ``,
- },
+ one: ReusableTransition,
+ },
+ template: ``,
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ components: {
+ one: ReusableTransitionWithAppear,
+ },
+ template: ``,
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ render() {
+ return h(ReusableTransition, null, {
+ default: () => null,
+ })
+ },
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ render() {
+ return h(ReusableTransitionWithAppear, null, {
+ default: () => null,
+ })
+ },
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ render() {
+ return h(ReusableTransitionWithAppear, null, {
+ default: () => [],
+ })
+ },
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ render() {
+ return h(ReusableTransition, null, {
+ default: () => [],
+ })
+ },
+ }),
+ ),
+ ).toBe(``)
+
+ expect(
+ await renderToString(
+ createApp({
+ components: {
+ one: ReusableTransition,
},
template: `foo
`,
}),
diff --git a/packages/server-renderer/src/helpers/ssrRenderSlot.ts b/packages/server-renderer/src/helpers/ssrRenderSlot.ts
index 19aa4ce63b7..2f93a12de9d 100644
--- a/packages/server-renderer/src/helpers/ssrRenderSlot.ts
+++ b/packages/server-renderer/src/helpers/ssrRenderSlot.ts
@@ -74,6 +74,8 @@ export function ssrRenderSlotInner(
)
} else if (fallbackRenderFn) {
fallbackRenderFn()
+ } else if (transition) {
+ push(``)
}
} else {
// ssr slot.
@@ -110,13 +112,19 @@ export function ssrRenderSlotInner(
end--
}
- for (let i = start; i < end; i++) {
- push(slotBuffer[i])
+ if (start < end) {
+ for (let i = start; i < end; i++) {
+ push(slotBuffer[i])
+ }
+ } else if (transition) {
+ push(``)
}
}
}
} else if (fallbackRenderFn) {
fallbackRenderFn()
+ } else if (transition) {
+ push(``)
}
}