mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
fix(nuxt3): allow customising page keys (#2859)
This commit is contained in:
parent
3125c72e09
commit
83a959a67b
@ -134,6 +134,29 @@ To display the `child.vue` component, you have to insert the `<NuxtNestedPage
|
|||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Child route keys
|
||||||
|
|
||||||
|
If you want more control over when the `<NuxtNestedPage>` component is re-rendered (for example, for transitions), you can either pass a string or function via the `childKey` prop, or you can define a `key` value via `definePageMeta`:
|
||||||
|
|
||||||
|
```html{}[pages/parent.vue]
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>I am the parent view</h1>
|
||||||
|
<NuxtNestedPage :child-key="someKey" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or alternatively:
|
||||||
|
|
||||||
|
```html{}[pages/child.vue]
|
||||||
|
<script setup>
|
||||||
|
definePageMeta({
|
||||||
|
key: route => route.fullPath
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
## Page Metadata
|
## Page Metadata
|
||||||
|
|
||||||
You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`:
|
You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`:
|
||||||
@ -175,6 +198,10 @@ definePageMeta({
|
|||||||
|
|
||||||
Of course, you are welcome to define metadata for your own use throughout your app. But some metadata defined with `definePageMeta` has a particular purpose:
|
Of course, you are welcome to define metadata for your own use throughout your app. But some metadata defined with `definePageMeta` has a particular purpose:
|
||||||
|
|
||||||
|
#### `key`
|
||||||
|
|
||||||
|
[See above](#child-route-keys).
|
||||||
|
|
||||||
#### `layout`
|
#### `layout`
|
||||||
|
|
||||||
You can define the layout used to render the route. This can be either false (to disable any layout), a string or a ref/computed, if you want to make it reactive in some way. [More about layouts](/docs/directory-structure/layouts).
|
You can define the layout used to render the route. This can be either false (to disable any layout), a string or a ref/computed, if you want to make it reactive in some way. [More about layouts](/docs/directory-structure/layouts).
|
||||||
|
@ -20,6 +20,12 @@ const route = useRoute()
|
|||||||
<NuxtLink to="/parent/b" class="n-link-base">
|
<NuxtLink to="/parent/b" class="n-link-base">
|
||||||
Parent (b)
|
Parent (b)
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
<button class="n-link-base" @click="$router.push(`/parent/reload-${(Math.random() * 100).toFixed()}`)">
|
||||||
|
Keyed child
|
||||||
|
</button>
|
||||||
|
<button class="n-link-base" @click="$router.push(`/parent/static-${(Math.random() * 100).toFixed()}`)">
|
||||||
|
Non-keyed child
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
13
examples/with-pages/pages/parent/reload-[id].vue
Normal file
13
examples/with-pages/pages/parent/reload-[id].vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Child reloaded: {{ reloads }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const reloads = useState('reload', () => 0)
|
||||||
|
onMounted(() => { reloads.value++ })
|
||||||
|
definePageMeta({
|
||||||
|
key: route => route.path
|
||||||
|
})
|
||||||
|
</script>
|
10
examples/with-pages/pages/parent/static-[id].vue
Normal file
10
examples/with-pages/pages/parent/static-[id].vue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Child reloaded: {{ reloads }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const reloads = useState('static', () => 0)
|
||||||
|
onMounted(() => { reloads.value++ })
|
||||||
|
</script>
|
@ -14,6 +14,7 @@ export interface PageMeta {
|
|||||||
[key: string]: any
|
[key: string]: any
|
||||||
transition?: false | TransitionProps
|
transition?: false | TransitionProps
|
||||||
layout?: false | string | Ref<false | string> | ComputedRef<false | string>
|
layout?: false | string | Ref<false | string> | ComputedRef<false | string>
|
||||||
|
key?: string | ((route: RouteLocationNormalizedLoaded) => string)
|
||||||
// TODO: https://github.com/vuejs/vue-next/issues/3652
|
// TODO: https://github.com/vuejs/vue-next/issues/3652
|
||||||
// keepalive?: false | KeepAliveProps
|
// keepalive?: false | KeepAliveProps
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<RouterView v-slot="{ Component }">
|
<RouterView v-slot="{ Component }">
|
||||||
<component :is="Component" :key="$route.path" />
|
<component :is="Component" :key="key" />
|
||||||
</RouterView>
|
</RouterView>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
|
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NuxtNestedPage'
|
name: 'NuxtNestedPage',
|
||||||
|
props: {
|
||||||
|
childKey: {
|
||||||
|
type: [Function, String] as unknown as () => string | ((route: RouteLocationNormalizedLoaded) => string),
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup (props) {
|
||||||
|
const route = useRoute()
|
||||||
|
const key = computed(() => {
|
||||||
|
const source = props.childKey ?? route.meta.key
|
||||||
|
return typeof source === 'function' ? source(route) : source
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
key
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<NuxtLayout v-if="Component" :name="layout || route.meta.layout">
|
<NuxtLayout v-if="Component" :name="layout || route.meta.layout">
|
||||||
<NuxtTransition :options="route.meta.transition ?? { name: 'page', mode: 'out-in' }">
|
<NuxtTransition :options="route.meta.transition ?? { name: 'page', mode: 'out-in' }">
|
||||||
<Suspense @pending="() => onSuspensePending(Component)" @resolve="() => onSuspenseResolved(Component)">
|
<Suspense @pending="() => onSuspensePending(Component)" @resolve="() => onSuspenseResolved(Component)">
|
||||||
<component :is="Component" :key="route.path" />
|
<component :is="Component" />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</NuxtTransition>
|
</NuxtTransition>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user