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'
|
import { PageRouteSymbol } from './injections'
|
||||||
|
|
||||||
export const RouteProvider = defineComponent({
|
export const RouteProvider = defineComponent({
|
||||||
name: 'RouteProvider',
|
|
||||||
props: {
|
props: {
|
||||||
vnode: {
|
vnode: {
|
||||||
type: Object as () => VNode,
|
type: Object as () => VNode,
|
||||||
|
@ -88,20 +88,27 @@ export default defineComponent({
|
|||||||
{ onAfterLeave: () => { nuxtApp.callHook('page:transition:finish', routeProps.Component) } }
|
{ onAfterLeave: () => { nuxtApp.callHook('page:transition:finish', routeProps.Component) } }
|
||||||
].filter(Boolean))
|
].filter(Boolean))
|
||||||
|
|
||||||
|
const keepaliveConfig = props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps)
|
||||||
vnode = _wrapIf(Transition, hasTransition && transitionProps,
|
vnode = _wrapIf(Transition, hasTransition && transitionProps,
|
||||||
wrapInKeepAlive(props.keepalive ?? routeProps.route.meta.keepalive ?? (defaultKeepaliveConfig as KeepAliveProps), h(Suspense, {
|
wrapInKeepAlive(keepaliveConfig, h(Suspense, {
|
||||||
suspensible: true,
|
suspensible: true,
|
||||||
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
|
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
|
||||||
onResolve: () => { nextTick(() => nuxtApp.callHook('page:finish', routeProps.Component).finally(done)) }
|
onResolve: () => { nextTick(() => nuxtApp.callHook('page:finish', routeProps.Component).finally(done)) }
|
||||||
}, {
|
}, {
|
||||||
default: () => h(RouteProvider, {
|
default: () => {
|
||||||
key: key || undefined,
|
const providerVNode = h(RouteProvider, {
|
||||||
vnode: routeProps.Component,
|
key: key || undefined,
|
||||||
route: routeProps.route,
|
vnode: routeProps.Component,
|
||||||
renderKey: key || undefined,
|
route: routeProps.route,
|
||||||
trackRootNodes: hasTransition,
|
renderKey: key || undefined,
|
||||||
vnodeRef: pageRef
|
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()
|
)).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) {
|
function normaliseIslandResult (result: NuxtIslandResponse) {
|
||||||
return {
|
return {
|
||||||
...result,
|
...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' },
|
{ charset: 'utf-8' },
|
||||||
{ name: 'description', content: 'Nuxt Fixture' }
|
{ name: 'description', content: 'Nuxt Fixture' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
keepalive: {
|
||||||
|
include: ['keepalive-in-config', 'not-keepalive-in-nuxtpage']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buildDir: process.env.NITRO_BUILD_DIR,
|
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