Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

docs(getting-started): add transitions page #7987

Merged
merged 7 commits into from
Oct 6, 2022
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 260 additions & 0 deletions docs/content/1.getting-started/5.transitions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
# Transitions
clemcode marked this conversation as resolved.
Show resolved Hide resolved

Nuxt uses the [`Transition`](https://vuejs.org/guide/built-ins/transition.html#the-transition-component) component under the hood to apply page transitions between the routes and layout transitions on the custom layouts.

Both page and layout transitions are applied using [`definePageMeta`](/api/utils/define-page-meta) utility function. You can add the `pageTransition` key to the `definePageMeta` of your page component to define a custom page transition for a specific route.

```vue [pages/some-page.vue]
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'fade-in'
}
})
</script>
```

When you apply a custom `layout` to your page component using `definePageMeta`, you can also add the `layoutTransition` key to define a layout transition for that custom layout.

```vue [pages/some-page.vue]
<script setup lang="ts">
definePageMeta({
layout: 'custom',
layoutTransition: {
name: 'slide-in'
}
})
</script>
```

::alert{type="warning"}
`<NuxtPage />` and `<NuxtLayout />` are already wrapped around Vue’s `<Transition />` component and you do not need to add the `<Transition>` component separately to your Nuxt pages or layouts.
::

## Global Settings

Default name of `pageTransition` is `page`, while the default name of `layoutTransition` is `layout`.

You can create CSS transitions with the name of `page` or `layout` to activate default page and layout transition respectively. Then, define the global CSS in `nuxt.config`.

::code-group

```ts [nuxt.config.ts]
atinux marked this conversation as resolved.
Show resolved Hide resolved
export default defineNuxtConfig({
css: [
// Global CSS
'@/assets/style/main.css',
]
})
```

```CSS [assets/style/main.css]
clemcode marked this conversation as resolved.
Show resolved Hide resolved
/* Page transition */
.page-enter-active {
animation: slideIn .5s ease-out both;
}

.page-leave-active {
animation: slideOut .5s ease-in both;
}

@keyframes slideIn {
0% {
transform: translate3d(-100%, 0, 0);
}

100% {
transform: translate3d(0, 0, 0);
}
}

@keyframes slideOut {
0% {
transform: translate3d(0, 0, 0);
}

100% {
transform: translate3d(100%, 0, 0);
}
}

/* Layout transition */
.layout-enter-active {
animation: bounce-in 0.5s;
}

.layout-leave-active {
animation: bounce-in 0.5s reverse;
}

@keyframes bounce-in {
0% {
transform: scale(0);
}

50% {
transform: scale(1.25);
}

100% {
transform: scale(1);
}
}
```

::

You can customize these default transition names globally using `nuxt.config`. Both `pageTransition` and `layoutTransition` keys accept [`TransitionProps`](https://vuejs.org/api/built-in-components.html#transition) as JSON serializable values where you can pass the `name`, `mode` and other valid transition-props of the custom CSS transition.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
pageTransition: {
name: 'fade',
mode: 'out-in' // default
},
layoutTransition: {
name: 'slide',
mode: 'out-in' // default
}
})
```

If you do modify the page Transition `name`, you will also have to rename the CSS classes accordingly.

::alert{type="warning"}
These globally defined page and layout transitions can be overridden with `definePageMeta` on an individual page.
::

### Override Global Transition

`definePageMeta` is used to define page or layout transitions for a single Nuxt page and override any page or layout transitions that are defined globally in `nuxt.config` file.

```vue [pages/some-page.vue]
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'bounce',
mode: 'out-in' // default
}
})
</script>
```

## Disable Transitions

`pageTransition` and `layoutTransition` can be disabled for a specific route if required.

```vue [pages/some-page.vue]
<script setup lang="ts">
definePageMeta({
pageTransition: false
layoutTransition: false
})
</script>
```

## JavaScript Hooks

For advanced use-cases, you can use JavaScript hooks to create highly dynamic and custom transitions for your Nuxt routes.

This way presents perfect use-cases for JavaScript animation libraries such as [GSAP](https://greensock.com/gsap/) or [Tween.js](https://createjs.com/tweenjs).

```vue [pages/some-page.vue]
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'custom-flip',
mode: 'out-in',
onBeforeEnter: (el) => {
console.log('Before enter...')
},
onEnter: (el, done) => {},
onAfterEnter: (el) => {}
}
})
</script>
```

::alert{type="info"}
Learn more about additional [JavaScript hooks](https://vuejs.org/guide/built-ins/transition.html#javascript-hooks) available in the `Transition` component.
::

## Dynamic Transitions

After disabling the default `pageTransition: false`, you can apply dynamic transitions using conditional logic to assign dynamic transitions directly to `to.meta.pageTransition` on your Nuxt pages.

This example also uses the pre-configured animation library, [Animate.css](https://animate.style/).

::code-group

```vue [pages/some-page.vue]
<script setup lang="ts">
const Router = useRouter()
onMounted(async () => {
Router.afterEach((to, from) => {
to.meta.pageTransition = +to.params.slug < +from.params.slug
? {
name: 'a',
mode: 'out-in',
appearActiveClass: "animate__animated animate__slideInRight",
enterActiveClass: "animate__animated animate__slideInRight",
leaveActiveClass: "animate__animated animate__slideOut",
duration: 500,
}
: {
name: 'a',
mode: 'out-in',
appearActiveClass: "animate__animated animate__slideInRight",
enterActiveClass: "animate__animated animate__slideInLeft",
leaveActiveClass: "animate__animated animate__slideOut",
duration: 500,
}
})
})

definePageMeta({
pageTransition: false,
})
</script>
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
app: {
head: {
link: [
{
rel: "stylesheet",
href: "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
}
]
}
}
})
```

::

::alert{type="info"}
Learn more about additional props to customize [transition classes](https://vuejs.org/api/built-in-components.html#transition) in the `Transition` component.
::

## Transition with NuxtPage

When `<NuxtPage />` is used in `app.vue`, transition-props can be passed directly as a component props to activate global transition.

```vue [app.vue]
<template>
<div>
<NuxtPage :transition="{
name: 'bounce',
mode: 'out-in'
}" />
</NuxtLayout>
</div>
</template>
```

::alert{type="warning"}
Remember, this page transition cannot be overridden with `definePageMeta` on individual pages.
::