Skip to content

Latest commit

 

History

History
260 lines (209 loc) · 6.5 KB

5.transitions.md

File metadata and controls

260 lines (209 loc) · 6.5 KB

Transitions

Nuxt uses the Transition 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 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.

<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.

<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

export default defineNuxtConfig({
  css: [
    // Global CSS
    '@/assets/style/main.css',
  ]
})
/* 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 as JSON serializable values where you can pass the name, mode and other valid transition-props of the custom CSS transition.

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.

<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.

<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 or Tween.js.

<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 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.

::code-group

<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>
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 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.

<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. ::