mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
fix(nuxt): provide route component names to KeepAlive
cache (#24024)
This commit is contained in:
parent
b90b631df0
commit
5493d60c4a
@ -4,7 +4,6 @@ import type { RouteLocation, RouteLocationNormalizedLoaded } from '#vue-router'
|
||||
import { PageRouteSymbol } from './injections'
|
||||
|
||||
export const RouteProvider = defineComponent({
|
||||
name: 'RouteProvider',
|
||||
props: {
|
||||
vnode: {
|
||||
type: Object as () => VNode,
|
||||
|
@ -88,20 +88,27 @@ export default defineComponent({
|
||||
{ onAfterLeave: () => { nuxtApp.callHook('page:transition:finish', routeProps.Component) } }
|
||||
].filter(Boolean))
|
||||
|
||||
const keepaliveConfig = props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps)
|
||||
vnode = _wrapIf(Transition, hasTransition && transitionProps,
|
||||
wrapInKeepAlive(props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps), h(Suspense, {
|
||||
wrapInKeepAlive(keepaliveConfig, h(Suspense, {
|
||||
suspensible: true,
|
||||
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
|
||||
onResolve: () => { nextTick(() => nuxtApp.callHook('page:finish', routeProps.Component).finally(done)) }
|
||||
}, {
|
||||
default: () => h(RouteProvider, {
|
||||
key: key || undefined,
|
||||
vnode: routeProps.Component,
|
||||
route: routeProps.route,
|
||||
renderKey: key || undefined,
|
||||
trackRootNodes: hasTransition,
|
||||
vnodeRef: pageRef
|
||||
})
|
||||
default: () => {
|
||||
const providerVNode = h(RouteProvider, {
|
||||
key: key || undefined,
|
||||
vnode: routeProps.Component,
|
||||
route: routeProps.route,
|
||||
renderKey: key || undefined,
|
||||
trackRootNodes: hasTransition,
|
||||
vnodeRef: pageRef
|
||||
})
|
||||
if (import.meta.client && keepaliveConfig) {
|
||||
(providerVNode.type as any).name = (routeProps.Component.type as any).name || (routeProps.Component.type as any).__name || 'RouteProvider'
|
||||
}
|
||||
return providerVNode
|
||||
}
|
||||
})
|
||||
)).default()
|
||||
|
||||
|
@ -2017,6 +2017,87 @@ describe.runIf(isDev())('component testing', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('keepalive', () => {
|
||||
it('should not keepalive by default', async () => {
|
||||
const { page, consoleLogs } = await renderPage('/keepalive')
|
||||
|
||||
const pageName = 'not-keepalive'
|
||||
await page.click(`#${pageName}`)
|
||||
await page.waitForTimeout(25)
|
||||
|
||||
expect(consoleLogs.map(l => l.text).filter(t => t.includes('keepalive'))).toEqual([`${pageName}: onMounted`])
|
||||
|
||||
await page.close()
|
||||
})
|
||||
|
||||
it('should not keepalive when included in app config but config in nuxt-page is not undefined', async () => {
|
||||
const { page, consoleLogs } = await renderPage('/keepalive')
|
||||
|
||||
const pageName = 'keepalive-in-config'
|
||||
await page.click(`#${pageName}`)
|
||||
await page.waitForTimeout(25)
|
||||
|
||||
expect(consoleLogs.map(l => l.text).filter(t => t.includes('keepalive'))).toEqual([`${pageName}: onMounted`])
|
||||
|
||||
await page.close()
|
||||
})
|
||||
|
||||
it('should not keepalive when included in app config but exclueded in nuxt-page', async () => {
|
||||
const { page, consoleLogs } = await renderPage('/keepalive')
|
||||
|
||||
const pageName = 'not-keepalive-in-nuxtpage'
|
||||
await page.click(`#${pageName}`)
|
||||
await page.waitForTimeout(25)
|
||||
|
||||
expect(consoleLogs.map(l => l.text).filter(t => t.includes('keepalive'))).toEqual([`${pageName}: onMounted`])
|
||||
|
||||
await page.close()
|
||||
})
|
||||
|
||||
it('should keepalive when included in nuxt-page', async () => {
|
||||
const { page, consoleLogs } = await renderPage('/keepalive')
|
||||
|
||||
const pageName = 'keepalive-in-nuxtpage'
|
||||
await page.click(`#${pageName}`)
|
||||
await page.waitForTimeout(25)
|
||||
|
||||
expect(consoleLogs.map(l => l.text).filter(t => t.includes('keepalive'))).toEqual([`${pageName}: onMounted`, `${pageName}: onActivated`])
|
||||
|
||||
await page.close()
|
||||
})
|
||||
|
||||
it('should preserve keepalive config when navigate routes in nuxt-page', async () => {
|
||||
const { page, consoleLogs } = await renderPage('/keepalive')
|
||||
|
||||
await page.click('#keepalive-in-nuxtpage')
|
||||
await page.waitForTimeout(25)
|
||||
await page.click('#keepalive-in-nuxtpage-2')
|
||||
await page.waitForTimeout(25)
|
||||
await page.click('#keepalive-in-nuxtpage')
|
||||
await page.waitForTimeout(25)
|
||||
await page.click('#not-keepalive')
|
||||
await page.waitForTimeout(25)
|
||||
await page.click('#keepalive-in-nuxtpage-2')
|
||||
await page.waitForTimeout(25)
|
||||
|
||||
expect(consoleLogs.map(l => l.text).filter(t => t.includes('keepalive'))).toEqual([
|
||||
'keepalive-in-nuxtpage: onMounted',
|
||||
'keepalive-in-nuxtpage: onActivated',
|
||||
'keepalive-in-nuxtpage: onDeactivated',
|
||||
'keepalive-in-nuxtpage-2: onMounted',
|
||||
'keepalive-in-nuxtpage-2: onActivated',
|
||||
'keepalive-in-nuxtpage: onActivated',
|
||||
'keepalive-in-nuxtpage-2: onDeactivated',
|
||||
'keepalive-in-nuxtpage: onDeactivated',
|
||||
'not-keepalive: onMounted',
|
||||
'keepalive-in-nuxtpage-2: onActivated',
|
||||
'not-keepalive: onUnmounted'
|
||||
])
|
||||
|
||||
await page.close()
|
||||
})
|
||||
})
|
||||
|
||||
function normaliseIslandResult (result: NuxtIslandResponse) {
|
||||
return {
|
||||
...result,
|
||||
|
6
test/fixtures/basic/composables/keep-alive.ts
vendored
Normal file
6
test/fixtures/basic/composables/keep-alive.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export function useLifecyleLogs (name: string) {
|
||||
onMounted(() => console.log(`${name}: onMounted`))
|
||||
onUnmounted(() => console.log(`${name}: onUnmounted`))
|
||||
onActivated(() => console.log(`${name}: onActivated`))
|
||||
onDeactivated(() => console.log(`${name}: onDeactivated`))
|
||||
}
|
3
test/fixtures/basic/nuxt.config.ts
vendored
3
test/fixtures/basic/nuxt.config.ts
vendored
@ -22,6 +22,9 @@ export default defineNuxtConfig({
|
||||
{ charset: 'utf-8' },
|
||||
{ name: 'description', content: 'Nuxt Fixture' }
|
||||
]
|
||||
},
|
||||
keepalive: {
|
||||
include: ['keepalive-in-config', 'not-keepalive-in-nuxtpage']
|
||||
}
|
||||
},
|
||||
buildDir: process.env.NITRO_BUILD_DIR,
|
||||
|
26
test/fixtures/basic/pages/keepalive.vue
vendored
Normal file
26
test/fixtures/basic/pages/keepalive.vue
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
const links = ['keepalive-in-config', 'not-keepalive', 'keepalive-in-nuxtpage', 'keepalive-in-nuxtpage-2', 'not-keepalive-in-nuxtpage']
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>Keepalive Test</h1>
|
||||
<NuxtLink
|
||||
id="keepalive-home"
|
||||
to="/keepalive"
|
||||
>
|
||||
Keepalive Home
|
||||
</NuxtLink>
|
||||
<div :style="{ display: 'flex', flexDirection: 'column', marginTop: '10px' }">
|
||||
<NuxtLink
|
||||
v-for="link in links"
|
||||
:id="link"
|
||||
:key="link"
|
||||
:to="`/keepalive/${link}`"
|
||||
>
|
||||
{{ link }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<NuxtPage :keepalive="{ include: ['keepalive-in-nuxtpage', 'keepalive-in-nuxtpage-2'], exclude: ['not-keepalive-in-nuxtpage'] }" />
|
||||
</div>
|
||||
</template>
|
9
test/fixtures/basic/pages/keepalive/keepalive-in-config.vue
vendored
Normal file
9
test/fixtures/basic/pages/keepalive/keepalive-in-config.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
useLifecyleLogs('keepalive-in-config')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>Keepalive in Config</h2>
|
||||
</div>
|
||||
</template>
|
9
test/fixtures/basic/pages/keepalive/keepalive-in-nuxtpage-2.vue
vendored
Normal file
9
test/fixtures/basic/pages/keepalive/keepalive-in-nuxtpage-2.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
useLifecyleLogs('keepalive-in-nuxtpage-2')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>Keepalive in `nuxt-page` 2</h2>
|
||||
</div>
|
||||
</template>
|
9
test/fixtures/basic/pages/keepalive/keepalive-in-nuxtpage.vue
vendored
Normal file
9
test/fixtures/basic/pages/keepalive/keepalive-in-nuxtpage.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
useLifecyleLogs('keepalive-in-nuxtpage')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>Keepalive in `nuxt-page`</h2>
|
||||
</div>
|
||||
</template>
|
9
test/fixtures/basic/pages/keepalive/not-keepalive-in-nuxtpage.vue
vendored
Normal file
9
test/fixtures/basic/pages/keepalive/not-keepalive-in-nuxtpage.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
useLifecyleLogs('not-keepalive-in-nuxtpage')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>Not Keepalive in `nuxt-page`</h2>
|
||||
</div>
|
||||
</template>
|
9
test/fixtures/basic/pages/keepalive/not-keepalive.vue
vendored
Normal file
9
test/fixtures/basic/pages/keepalive/not-keepalive.vue
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
useLifecyleLogs('not-keepalive')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>Not Keepalive</h2>
|
||||
</div>
|
||||
</template>
|
Loading…
Reference in New Issue
Block a user