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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
260 changes: 260 additions & 0 deletions docs/content/1.getting-started/5.transitions.md
@@ -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.
::