nuxt logo

문서 번역(비공식)

전환

Vue 또는 네이티브 브라우저 View Transitions를 사용하여 페이지 및 레이아웃 간 전환을 적용합니다.

Nuxt는 Vue의 <Transition> 컴포넌트를 활용하여 페이지 및 레이아웃 간 전환을 적용합니다.

페이지 전환

모든 페이지에 자동 전환을 적용하려면 페이지 전환을 활성화할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: { name: 'page', mode: 'out-in' }
  },
})

페이지뿐만 아니라 레이아웃도 변경하는 경우, 여기서 설정한 페이지 전환은 실행되지 않습니다. 대신 레이아웃 전환을 설정해야 합니다.

페이지 간 전환을 추가하려면, 다음 CSS를 app.vue에 추가하세요:

<template>
  <NuxtPage />
</template>

<style>
.page-enter-active,
.page-leave-active {
  transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
  opacity: 0;
  filter: blur(1rem);
}
</style>

페이지 간 탐색 시 다음과 같은 결과가 생성됩니다:

페이지에 다른 전환을 설정하려면, 페이지의 definePageMeta에서 pageTransition 키를 설정하세요:

definePageMeta({
  pageTransition: {
    name: 'rotate'
  }
})

소개 페이지로 이동하면 3D 회전 효과가 추가됩니다:

레이아웃 전환

모든 레이아웃에 자동 전환을 적용하려면 레이아웃 전환을 활성화할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    layoutTransition: { name: 'layout', mode: 'out-in' }
  },
})

페이지 및 레이아웃 간 전환을 추가하려면, 다음 CSS를 app.vue에 추가하세요:

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

<style>
.layout-enter-active,
.layout-leave-active {
  transition: all 0.4s;
}
.layout-enter-from,
.layout-leave-to {
  filter: grayscale(1);
}
</style>

페이지 간 탐색 시 다음과 같은 결과가 생성됩니다:

pageTransition과 유사하게, definePageMeta를 사용하여 페이지 컴포넌트에 사용자 정의 layoutTransition을 적용할 수 있습니다:

pages/about.vue
definePageMeta({
  layout: 'orange',
  layoutTransition: {
    name: 'slide-in'
  }
})

전역 설정

nuxt.config를 사용하여 이러한 기본 전환 이름을 전역적으로 사용자 정의할 수 있습니다.

pageTransitionlayoutTransition 키는 JSON 직렬화 가능한 값으로 TransitionProps를 허용하며, 여기서 name, mode 및 사용자 정의 CSS 전환의 다른 유효한 전환 속성을 전달할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: {
      name: 'fade',
      mode: 'out-in' // 기본값
    },
    layoutTransition: {
      name: 'slide',
      mode: 'out-in' // 기본값
    }
  }
})

name 속성을 변경하면 CSS 클래스 이름도 이에 맞게 변경해야 합니다.

전역 전환 속성을 재정의하려면, definePageMeta를 사용하여 단일 Nuxt 페이지에 대한 페이지 또는 레이아웃 전환을 정의하고 nuxt.config 파일에 전역적으로 정의된 페이지 또는 레이아웃 전환을 재정의하세요.

pages/some-page.vue
definePageMeta({
  pageTransition: {
    name: 'bounce',
    mode: 'out-in' // 기본값
  }
})

전환 비활성화

특정 경로에 대해 pageTransitionlayoutTransition을 비활성화할 수 있습니다:

pages/some-page.vue
definePageMeta({
  pageTransition: false,
  layoutTransition: false
})

또는 nuxt.config에서 전역적으로:

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: false,
    layoutTransition: false
  }
})

JavaScript 훅

고급 사용 사례를 위해 JavaScript 훅을 사용하여 Nuxt 페이지에 대해 매우 동적이고 사용자 정의된 전환을 만들 수 있습니다.

이 방법은 GSAP과 같은 JavaScript 애니메이션 라이브러리에 완벽한 사용 사례를 제공합니다.

pages/some-page.vue
definePageMeta({
  pageTransition: {
    name: 'custom-flip',
    mode: 'out-in',
    onBeforeEnter: (el) => {
      console.log('Before enter...')
    },
    onEnter: (el, done) => {},
    onAfterEnter: (el) => {}
  }
})

Transition 컴포넌트에서 사용할 수 있는 추가 JavaScript 훅에 대해 더 알아보세요.

동적 전환

조건부 로직을 사용하여 동적 전환을 적용하려면, 인라인 미들웨어를 활용하여 to.meta.pageTransition에 다른 전환 이름을 할당할 수 있습니다.

<script setup lang="ts">
definePageMeta({
  pageTransition: {
    name: 'slide-right',
    mode: 'out-in'
  },
  middleware (to, from) {
    if (to.meta.pageTransition && typeof to.meta.pageTransition !== 'boolean')
      to.meta.pageTransition.name = +to.params.id! > +from.params.id! ? 'slide-left' : 'slide-right'
  }
})
</script>

<template>
  <h1>#{{ $route.params.id }}</h1>
</template>

<style>
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
  transition: all 0.2s;
}
.slide-left-enter-from {
  opacity: 0;
  transform: translate(50px, 0);
}
.slide-left-leave-to {
  opacity: 0;
  transform: translate(-50px, 0);
}
.slide-right-enter-from {
  opacity: 0;
  transform: translate(-50px, 0);
}
.slide-right-leave-to {
  opacity: 0;
  transform: translate(50px, 0);
}
</style>

페이지는 이제 다음 id로 이동할 때 slide-left 전환을 적용하고 이전에는 slide-right를 적용합니다:

NuxtPage와의 전환

app.vue에서 <NuxtPage />가 사용될 때, 전환은 transition prop으로 전역적으로 활성화될 수 있습니다.

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

이 페이지 전환은 개별 페이지에서 definePageMeta로 재정의할 수 없습니다.

View Transitions API (실험적)

Nuxt는 View Transitions API의 실험적 구현을 제공합니다 (자세한 내용은 MDN을 참조하세요). 이는 서로 관련 없는 요소 간의 전환을 포함하여 네이티브 브라우저 전환을 구현하는 흥미로운 새로운 방법입니다.

https://nuxt-view-transitions.surge.sh에서 데모를 확인하고 StackBlitz의 소스를 확인할 수 있습니다.

Nuxt 통합은 활발히 개발 중이며, 구성 파일에서 experimental.viewTransition 옵션을 사용하여 활성화할 수 있습니다:

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    viewTransition: true
  }
})

가능한 값은 false, true, 또는 'always'입니다.

true로 설정하면, 사용자의 브라우저가 prefers-reduced-motion: reduce와 일치하는 경우 Nuxt는 전환을 적용하지 않습니다 (권장). always로 설정하면 Nuxt는 항상 전환을 적용하며 사용자의 선호를 존중하는 것은 여러분의 몫입니다.

기본적으로, 모든 페이지에 대해 뷰 전환이 활성화되어 있지만, 다른 전역 기본값을 설정할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    // 전역적으로 뷰 전환 비활성화, 페이지별로 선택적 활성화
    viewTransition: false
  },
})

페이지의 definePageMeta에서 viewTransition 키를 설정하여 페이지에 대한 기본 viewTransition 값을 재정의할 수 있습니다:

pages/about.vue
definePageMeta({
  viewTransition: false
})

페이지별로 뷰 전환을 재정의하려면 experimental.viewTransition 옵션을 활성화해야만 효과가 있습니다.

Vue 전환인 pageTransitionlayoutTransition을 사용하여 새로운 View Transitions API와 동일한 결과를 얻으려는 경우, 사용자의 브라우저가 최신 네이티브 웹 API를 지원하는 경우 Vue 전환을 비활성화 하고 싶을 수 있습니다. 이를 위해 ~/middleware/disable-vue-transitions.global.ts를 다음 내용으로 생성할 수 있습니다:

export default defineNuxtRouteMiddleware(to => {
  if (import.meta.server || !document.startViewTransition) { return }

  // 내장된 Vue 전환 비활성화
  to.meta.pageTransition = false
  to.meta.layoutTransition = false
})

알려진 문제

  • 페이지 설정 함수 내에서 데이터 가져오기를 수행하는 경우, 이 기능을 사용하는 것을 재고할 수 있습니다. (설계상, View Transitions는 전환이 진행되는 동안 DOM 업데이트를 완전히 동결합니다.) 우리는 <Suspense>가 해결되기 직전에 View Transition을 제한하는 것을 고려하고 있지만, 이 기능을 채택할지 신중히 고려해야 할 수도 있습니다.