Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(runtime-dom): TransitionGroup does not handle async components that have not been resolved #7901

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
182bc2f
fix(runtime-dom): transitionGrop does not handle asynchronous compone…
baiwusanyu-c Mar 16, 2023
a9b9088
fix(runtime-dom): added unit test
baiwusanyu-c Mar 16, 2023
0d71e97
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Mar 17, 2023
014e4a3
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Mar 20, 2023
c6f352f
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Mar 23, 2023
55ca986
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Mar 24, 2023
4e33e97
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Mar 27, 2023
0ea2111
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 5, 2023
e13c48e
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 6, 2023
3978737
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 10, 2023
3b0a3e2
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 11, 2023
aa306bd
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 14, 2023
b7895d8
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 17, 2023
13451ce
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 19, 2023
852cff7
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 20, 2023
2d03e56
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 24, 2023
e39dd80
Merge branch 'vuejs:main' into bwsy/fix/transitionGrop
baiwusanyu-c Apr 25, 2023
3555c07
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 4, 2023
be32767
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 12, 2023
c4e2c81
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 12, 2023
1943dc4
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 16, 2023
2768d04
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 17, 2023
91c92aa
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c May 22, 2023
8435cb8
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Aug 22, 2023
5478ac7
Merge branch 'main' into bwsy/fix/transitionGrop
baiwusanyu-c Jan 3, 2024
844ec00
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/runtime-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export {
export { provide, inject, hasInjectionContext } from './apiInject'
export { nextTick } from './scheduler'
export { defineComponent } from './apiDefineComponent'
export { defineAsyncComponent } from './apiAsyncComponent'
export { defineAsyncComponent, isAsyncWrapper } from './apiAsyncComponent'
export { useAttrs, useSlots } from './apiSetupHelpers'

// <script setup> API ----------------------------------------------------------
Expand Down
18 changes: 17 additions & 1 deletion packages/runtime-dom/src/components/TransitionGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
warn,
} from '@vue/runtime-core'
import { extend } from '@vue/shared'
import { isAsyncWrapper } from '@vue/runtime-core'

const positionMap = new WeakMap<VNode, DOMRect>()
const newPositionMap = new WeakMap<VNode, DOMRect>()
Expand Down Expand Up @@ -56,6 +57,15 @@ const TransitionGroupImpl: ComponentOptions = {
if (!prevChildren.length) {
return
}

// #7898
if (
isAsyncWrapper(prevChildren[0]) &&
prevChildren[0].component &&
!prevChildren[0].component.asyncResolved
) {
return
}
const moveClass = props.moveClass || `${props.name || 'v'}-move`

if (
Expand Down Expand Up @@ -134,7 +144,13 @@ const TransitionGroupImpl: ComponentOptions = {
child,
resolveTransitionHooks(child, cssTransitionProps, state, instance),
)
positionMap.set(child, (child.el as Element).getBoundingClientRect())
// #7898
;(child.el as Element).getBoundingClientRect
? positionMap.set(
child,
(child.el as Element).getBoundingClientRect(),
)
: positionMap.set(child, new DOMRect())
}
}

Expand Down
58 changes: 58 additions & 0 deletions packages/vue/__tests__/e2e/TransitionGroup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,4 +508,62 @@ describe('e2e: TransitionGroup', () => {

expect(`<TransitionGroup> children must be keyed`).toHaveBeenWarned()
})

// #7898
// When `TransitionGroup` is updated,
// the async component does not have resolve and will not report an error
// It seems that this error cannot be caught in puppeteer,
// but we can still achieve single testing by checking whether the expected rendering is met
test(
'TransitionGroup is updated & the async component does not have resolve',
async () => {
await page().evaluate(() => {
const { createApp, defineAsyncComponent, shallowRef, onMounted } = (
window as any
).Vue
createApp({
template: `
<div id="container">
<transition-group name="test">
<component :is="component"
v-for="(component, index) in components"
:key="index"
</transition-group>
</div>
`,
setup: () => {
const components = shallowRef([newComponent(1)])
function sleep(millis: number, index: number) {
return new Promise(resolve =>
setTimeout(() => {
resolve({
render() {
return `foo${index}`
},
})
}, millis),
)
}

function newComponent(index: number) {
return defineAsyncComponent(() => sleep(1000, index))
}

function addComponent() {
components.value = [...components.value, newComponent(2)]
}
onMounted(() => {
addComponent()
})

return { components }
},
}).mount('#app')
})

await transitionFinish(1000)
expect(await html('#container')).toBe('foo1foo2')
},
E2E_TIMEOUT,
)
})