@@ -18,6 +18,7 @@ import { toRaw } from '@vue/reactivity'
18
18
import { ErrorCodes , callWithAsyncErrorHandling } from '../errorHandling'
19
19
import { PatchFlags , ShapeFlags , isArray , isFunction } from '@vue/shared'
20
20
import { onBeforeUnmount , onMounted } from '../apiLifecycle'
21
+ import { isTeleport } from './Teleport'
21
22
import type { RendererElement } from '../renderer'
22
23
import { SchedulerJobFlags } from '../scheduler'
23
24
@@ -152,27 +153,7 @@ const BaseTransitionImpl: ComponentOptions = {
152
153
return
153
154
}
154
155
155
- let child : VNode = children [ 0 ]
156
- if ( children . length > 1 ) {
157
- let hasFound = false
158
- // locate first non-comment child
159
- for ( const c of children ) {
160
- if ( c . type !== Comment ) {
161
- if ( __DEV__ && hasFound ) {
162
- // warn more than one non-comment child
163
- warn (
164
- '<transition> can only be used on a single element or component. ' +
165
- 'Use <transition-group> for lists.' ,
166
- )
167
- break
168
- }
169
- child = c
170
- hasFound = true
171
- if ( ! __DEV__ ) break
172
- }
173
- }
174
- }
175
-
156
+ const child : VNode = findNonCommentChild ( children )
176
157
// there's no need to track reactivity for these props so use the raw
177
158
// props for a bit better perf
178
159
const rawProps = toRaw ( props )
@@ -194,7 +175,7 @@ const BaseTransitionImpl: ComponentOptions = {
194
175
195
176
// in the case of <transition><keep-alive/></transition>, we need to
196
177
// compare the type of the kept-alive children.
197
- const innerChild = getKeepAliveChild ( child )
178
+ const innerChild = getInnerChild ( child )
198
179
if ( ! innerChild ) {
199
180
return emptyPlaceholder ( child )
200
181
}
@@ -208,7 +189,7 @@ const BaseTransitionImpl: ComponentOptions = {
208
189
setTransitionHooks ( innerChild , enterHooks )
209
190
210
191
const oldChild = instance . subTree
211
- const oldInnerChild = oldChild && getKeepAliveChild ( oldChild )
192
+ const oldInnerChild = oldChild && getInnerChild ( oldChild )
212
193
213
194
// handle mode
214
195
if (
@@ -268,6 +249,30 @@ if (__COMPAT__) {
268
249
BaseTransitionImpl . __isBuiltIn = true
269
250
}
270
251
252
+ function findNonCommentChild ( children : VNode [ ] ) : VNode {
253
+ let child : VNode = children [ 0 ]
254
+ if ( children . length > 1 ) {
255
+ let hasFound = false
256
+ // locate first non-comment child
257
+ for ( const c of children ) {
258
+ if ( c . type !== Comment ) {
259
+ if ( __DEV__ && hasFound ) {
260
+ // warn more than one non-comment child
261
+ warn (
262
+ '<transition> can only be used on a single element or component. ' +
263
+ 'Use <transition-group> for lists.' ,
264
+ )
265
+ break
266
+ }
267
+ child = c
268
+ hasFound = true
269
+ if ( ! __DEV__ ) break
270
+ }
271
+ }
272
+ }
273
+ return child
274
+ }
275
+
271
276
// export the public type for h/tsx inference
272
277
// also to avoid inline import() in generated d.ts files
273
278
export const BaseTransition = BaseTransitionImpl as unknown as {
@@ -458,8 +463,12 @@ function emptyPlaceholder(vnode: VNode): VNode | undefined {
458
463
}
459
464
}
460
465
461
- function getKeepAliveChild ( vnode : VNode ) : VNode | undefined {
466
+ function getInnerChild ( vnode : VNode ) : VNode | undefined {
462
467
if ( ! isKeepAlive ( vnode ) ) {
468
+ if ( isTeleport ( vnode . type ) && vnode . children ) {
469
+ return findNonCommentChild ( vnode . children as VNode [ ] )
470
+ }
471
+
463
472
return vnode
464
473
}
465
474
// #7121 ensure get the child component subtree in case
0 commit comments