diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index ca21030dc..f7d6b91a7 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -149,7 +149,8 @@ export function setRef( warn('Invalid template ref type:', ref, `(${typeof ref})`) } } - if (value) { + + if (value || (vnode.transition && !vnode.transition.persisted)) { // #1789: for non-null values, set them after render // null values means this is unmount and it should not overwrite another // ref with the same key diff --git a/packages/vue/__tests__/e2e/TransitionGroup.spec.ts b/packages/vue/__tests__/e2e/TransitionGroup.spec.ts index 62d89db4e..2f2b46643 100644 --- a/packages/vue/__tests__/e2e/TransitionGroup.spec.ts +++ b/packages/vue/__tests__/e2e/TransitionGroup.spec.ts @@ -297,6 +297,57 @@ describe('e2e: TransitionGroup', () => { E2E_TIMEOUT, ) + test( + 'ref', + async () => { + await page().evaluate(() => { + const { createApp, ref } = (window as any).Vue + createApp({ + template: ` +
+ +
{{item}}
+
+
+ + `, + setup: () => { + const items = ref(['a', 'b', 'c']) + const click = () => (items.value = ['d', 'b', 'a']) + const itemRef = ref() + return { click, items, itemRef } + }, + }).mount('#app') + }) + expect(await html('#container')).toBe( + `
a
` + + `
b
` + + `
c
`, + ) + + expect(await htmlWhenTransitionStart()).toBe( + `
d
` + + `
b
` + + `
a
` + + `
c
`, + ) + await nextFrame() + expect(await html('#container')).toBe( + `
d
` + + `
b
` + + `
a
` + + `
c
`, + ) + await transitionFinish(duration * 2) + expect(await html('#container')).toBe( + `
d
` + + `
b
` + + `
a
`, + ) + }, + E2E_TIMEOUT, + ) + test( 'dynamic name', async () => {