|
|
@@ -1427,9 +1427,11 @@ describe('e2e: Transition', () => {
|
|
|
},
|
|
|
E2E_TIMEOUT,
|
|
|
)
|
|
|
+ })
|
|
|
|
|
|
+ describe('transition with KeepAlive', () => {
|
|
|
test(
|
|
|
- 'w/ KeepAlive + unmount innerChild',
|
|
|
+ 'unmount innerChild (out-in mode)',
|
|
|
async () => {
|
|
|
const unmountSpy = vi.fn()
|
|
|
await page().exposeFunction('unmountSpy', unmountSpy)
|
|
|
@@ -1484,6 +1486,173 @@ describe('e2e: Transition', () => {
|
|
|
},
|
|
|
E2E_TIMEOUT,
|
|
|
)
|
|
|
+
|
|
|
+ // #11775
|
|
|
+ test(
|
|
|
+ 'switch child then update include (out-in mode)',
|
|
|
+ async () => {
|
|
|
+ const onUpdatedSpyA = vi.fn()
|
|
|
+ const onUnmountedSpyC = vi.fn()
|
|
|
+
|
|
|
+ await page().exposeFunction('onUpdatedSpyA', onUpdatedSpyA)
|
|
|
+ await page().exposeFunction('onUnmountedSpyC', onUnmountedSpyC)
|
|
|
+
|
|
|
+ await page().evaluate(() => {
|
|
|
+ const { onUpdatedSpyA, onUnmountedSpyC } = window as any
|
|
|
+ const { createApp, ref, shallowRef, h, onUpdated, onUnmounted } = (
|
|
|
+ window as any
|
|
|
+ ).Vue
|
|
|
+ createApp({
|
|
|
+ template: `
|
|
|
+ <div id="container">
|
|
|
+ <transition mode="out-in">
|
|
|
+ <KeepAlive :include="includeRef">
|
|
|
+ <component :is="current" />
|
|
|
+ </KeepAlive>
|
|
|
+ </transition>
|
|
|
+ </div>
|
|
|
+ <button id="switchToB" @click="switchToB">switchToB</button>
|
|
|
+ <button id="switchToC" @click="switchToC">switchToC</button>
|
|
|
+ <button id="switchToA" @click="switchToA">switchToA</button>
|
|
|
+ `,
|
|
|
+ components: {
|
|
|
+ CompA: {
|
|
|
+ name: 'CompA',
|
|
|
+ setup() {
|
|
|
+ onUpdated(onUpdatedSpyA)
|
|
|
+ return () => h('div', 'CompA')
|
|
|
+ },
|
|
|
+ },
|
|
|
+ CompB: {
|
|
|
+ name: 'CompB',
|
|
|
+ setup() {
|
|
|
+ return () => h('div', 'CompB')
|
|
|
+ },
|
|
|
+ },
|
|
|
+ CompC: {
|
|
|
+ name: 'CompC',
|
|
|
+ setup() {
|
|
|
+ onUnmounted(onUnmountedSpyC)
|
|
|
+ return () => h('div', 'CompC')
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ setup: () => {
|
|
|
+ const includeRef = ref(['CompA', 'CompB', 'CompC'])
|
|
|
+ const current = shallowRef('CompA')
|
|
|
+ const switchToB = () => (current.value = 'CompB')
|
|
|
+ const switchToC = () => (current.value = 'CompC')
|
|
|
+ const switchToA = () => {
|
|
|
+ current.value = 'CompA'
|
|
|
+ includeRef.value = ['CompA']
|
|
|
+ }
|
|
|
+ return { current, switchToB, switchToC, switchToA, includeRef }
|
|
|
+ },
|
|
|
+ }).mount('#app')
|
|
|
+ })
|
|
|
+
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div>CompA</div>')
|
|
|
+
|
|
|
+ await click('#switchToB')
|
|
|
+ await nextTick()
|
|
|
+ await click('#switchToC')
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div class="">CompC</div>')
|
|
|
+
|
|
|
+ await click('#switchToA')
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div class="">CompA</div>')
|
|
|
+
|
|
|
+ // expect CompA only update once
|
|
|
+ expect(onUpdatedSpyA).toBeCalledTimes(1)
|
|
|
+ expect(onUnmountedSpyC).toBeCalledTimes(1)
|
|
|
+ },
|
|
|
+ E2E_TIMEOUT,
|
|
|
+ )
|
|
|
+
|
|
|
+ // #10827
|
|
|
+ test(
|
|
|
+ 'switch and update child then update include (out-in mode)',
|
|
|
+ async () => {
|
|
|
+ const onUnmountedSpyB = vi.fn()
|
|
|
+ await page().exposeFunction('onUnmountedSpyB', onUnmountedSpyB)
|
|
|
+
|
|
|
+ await page().evaluate(() => {
|
|
|
+ const { onUnmountedSpyB } = window as any
|
|
|
+ const {
|
|
|
+ createApp,
|
|
|
+ ref,
|
|
|
+ shallowRef,
|
|
|
+ h,
|
|
|
+ provide,
|
|
|
+ inject,
|
|
|
+ onUnmounted,
|
|
|
+ } = (window as any).Vue
|
|
|
+ createApp({
|
|
|
+ template: `
|
|
|
+ <div id="container">
|
|
|
+ <transition name="test-anim" mode="out-in">
|
|
|
+ <KeepAlive :include="includeRef">
|
|
|
+ <component :is="current" />
|
|
|
+ </KeepAlive>
|
|
|
+ </transition>
|
|
|
+ </div>
|
|
|
+ <button id="switchToA" @click="switchToA">switchToA</button>
|
|
|
+ <button id="switchToB" @click="switchToB">switchToB</button>
|
|
|
+ `,
|
|
|
+ components: {
|
|
|
+ CompA: {
|
|
|
+ name: 'CompA',
|
|
|
+ setup() {
|
|
|
+ const current = inject('current')
|
|
|
+ return () => h('div', current.value)
|
|
|
+ },
|
|
|
+ },
|
|
|
+ CompB: {
|
|
|
+ name: 'CompB',
|
|
|
+ setup() {
|
|
|
+ const current = inject('current')
|
|
|
+ onUnmounted(onUnmountedSpyB)
|
|
|
+ return () => h('div', current.value)
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ setup: () => {
|
|
|
+ const includeRef = ref(['CompA'])
|
|
|
+ const current = shallowRef('CompA')
|
|
|
+ provide('current', current)
|
|
|
+
|
|
|
+ const switchToB = () => {
|
|
|
+ current.value = 'CompB'
|
|
|
+ includeRef.value = ['CompA', 'CompB']
|
|
|
+ }
|
|
|
+ const switchToA = () => {
|
|
|
+ current.value = 'CompA'
|
|
|
+ includeRef.value = ['CompA']
|
|
|
+ }
|
|
|
+ return { current, switchToB, switchToA, includeRef }
|
|
|
+ },
|
|
|
+ }).mount('#app')
|
|
|
+ })
|
|
|
+
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div>CompA</div>')
|
|
|
+
|
|
|
+ await click('#switchToB')
|
|
|
+ await transitionFinish()
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div class="">CompB</div>')
|
|
|
+
|
|
|
+ await click('#switchToA')
|
|
|
+ await transitionFinish()
|
|
|
+ await transitionFinish()
|
|
|
+ expect(await html('#container')).toBe('<div class="">CompA</div>')
|
|
|
+
|
|
|
+ expect(onUnmountedSpyB).toBeCalledTimes(1)
|
|
|
+ },
|
|
|
+ E2E_TIMEOUT,
|
|
|
+ )
|
|
|
})
|
|
|
|
|
|
describe('transition with Suspense', () => {
|