透過 100 多個訣竅來學習 Nuxt!

轉場效果

使用 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

<script setup lang="ts">
definePageMeta
({
pageTransition
: {
name
: 'rotate'
} }) </script>

移動到 about 頁面將會新增 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
<script setup lang="ts">
definePageMeta
({
layout
: 'orange',
layoutTransition
: {
name
: 'slide-in'
} }) </script>

全域設定

您可以使用 nuxt.config 全域自訂這些預設轉場名稱。

pageTransitionlayoutTransition 這兩個鍵都接受 TransitionProps 作為 JSON 可序列化的值,您可以在其中傳遞 namemode 以及其他有效的 CSS 自訂轉場屬性。

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
pageTransition
: {
name
: 'fade',
mode
: 'out-in' // default
},
layoutTransition
: {
name
: 'slide',
mode
: 'out-in' // default
} } })
如果您更改 name 屬性,您也必須相應地重新命名 CSS 類別。

若要覆寫全域轉場屬性,請使用 definePageMeta 來定義單一 Nuxt 頁面或版面的轉場效果,並覆寫在 nuxt.config 檔案中全域定義的任何頁面或版面轉場。

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

停用轉場效果

可以針對特定路由停用 pageTransitionlayoutTransition

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

或是在 nuxt.config 中全域停用

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

JavaScript Hook

對於進階的使用情境,您可以使用 JavaScript Hook 為您的 Nuxt 頁面建立高度動態和自訂的轉場效果。

這種方式非常適合使用 JavaScript 動畫庫,例如 GSAP

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>
請參閱 Transition 元件,以了解更多可用的 JavaScript Hook。

動態轉場效果

若要使用條件邏輯套用動態轉場效果,您可以利用內聯的 中介層,為 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 轉場效果,而前往上一個 id 時則套用 slide-right

使用 NuxtPage 進行轉場

當在 app.vue 中使用 <NuxtPage /> 時,可以使用 transition prop 設定轉場效果,以全域啟用轉場。

app.vue
<template>
  <div>
    <NuxtLayout>
      <NuxtPage :transition="{
        name: 'bounce',
        mode: 'out-in'
      }" />
    </NuxtLayout>
  </div>
</template>
請記住,此頁面轉場效果無法使用個別頁面上的 definePageMeta 覆寫。

視圖轉場 API (實驗性)

Nuxt 隨附了 視圖轉場 API 的實驗性實作 (請參閱 MDN)。這是一種令人興奮的新方式,可以實作原生瀏覽器轉場效果,這(除其他外)能夠在不同頁面上不相關的元素之間進行轉場。

您可以在 https://nuxt-view-transitions.surge.sh 上查看演示,並在 StackBlitz 上查看原始碼

Nuxt 整合正在積極開發中,但可以使用設定檔中的 experimental.viewTransition 選項啟用。

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

可能的值為:falsetrue'always'

如果設定為 true,則如果使用者的瀏覽器符合 prefers-reduced-motion: reduce(建議),Nuxt 將不會套用轉場效果。如果設定為 always,Nuxt 將始終套用轉場效果,並且您有責任尊重使用者的偏好。

預設情況下,視圖轉場會為所有 頁面啟用,但您可以設定不同的全域預設值。

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
// Disable view transitions globally, and opt-in on a per page basis
viewTransition
: false
}, })

可以透過在頁面的 definePageMeta 中設定 viewTransition 鍵來覆寫頁面的預設 viewTransition

pages/about.vue
<script setup lang="ts">
definePageMeta
({
viewTransition
: false
}) </script>
只有在您啟用了 experimental.viewTransition 選項的情況下,逐頁覆寫視圖轉場才會生效。

如果您也使用 Vue 轉場效果(例如 pageTransitionlayoutTransition(請參閱上文))來實現與新的視圖轉場 API 相同的結果,那麼您可能希望在使用者瀏覽器支援較新的原生 Web API 時停用 Vue 轉場效果。您可以透過使用以下內容建立 ~/middleware/disable-vue-transitions.global.ts 來做到這一點

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

  // Disable built-in Vue transitions
  to.meta.pageTransition = false
  to.meta.layoutTransition = false
})

已知問題

  • 如果您在頁面設定函式內執行資料擷取,您可能需要考慮暫時不要使用此功能。(依設計,視圖轉場會在進行時完全凍結 DOM 更新。)我們正在研究將視圖轉場限制在 <Suspense> 解析之前的最後時刻,但在這段期間,如果這種情況符合您的情況,您可能需要仔細考慮是否採用此功能。