Skip to content

Nuxt.js Page Transitions

ภาพรวม

Nuxt.js มีระบบจัดการการเปลี่ยนหน้า (transitions) ที่ช่วยให้คุณเพิ่มเอฟเฟกต์การเปลี่ยนระหว่างหน้าเว็บได้อย่างง่ายดาย โดยใช้ CSS หรือ JavaScript

การตั้งค่าพื้นฐาน

1. เปิดใช้งาน Page Transitions

เพิ่มการตั้งค่าใน nuxt.config.ts:

typescript
export default defineNuxtConfig({
  app: {
    // ตั้งค่าการเปลี่ยนหน้าทั่วไป
    pageTransition: {
      name: "page",
      mode: "out-in",
    },
  },
});

2. เพิ่ม CSS สำหรับ Transition

เพิ่มสไตล์ใน app.vue:

vue
<template>
  <NuxtPage />
</template>

<style>
/* เอฟเฟกต์ Fade In/Out */
.page-enter-active,
.page-leave-active {
  transition: all 0.3s;
}
.page-enter-from,
.page-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
</style>

กำหนด Transition เฉพาะหน้า

ใช้ definePageMeta เพื่อกำหนดการเปลี่ยนหน้าแบบเฉพาะหน้า:

vue
<script setup>
definePageMeta({
  pageTransition: {
    name: "slide",
    mode: "out-in",
  },
});
</script>

<template>
  <div>
    <h1>เกี่ยวกับเรา</h1>
    <NuxtLink to="/">กลับหน้าหลัก</NuxtLink>
  </div>
</template>

<style scoped>
/* เอฟเฟกต์ Slide */
.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s ease;
}
.slide-enter-from {
  transform: translateX(100%);
  opacity: 0;
}
.slide-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}
</style>

Layout Transitions

1. เปิดใช้งาน Layout Transitions

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

2. เพิ่ม CSS สำหรับ Layout Transition

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

<style>
.layout-enter-active,
.layout-leave-active {
  transition: all 0.4s;
}
.layout-enter-from,
.layout-leave-to {
  opacity: 0;
  transform: scale(0.95);
}
</style>

JavaScript Hooks

ใช้ JavaScript Hooks สำหรับเอฟเฟกต์พิเศษ:

vue
<script setup>
definePageMeta({
  pageTransition: {
    name: "custom",
    mode: "out-in",
    onBeforeEnter: (el) => {
      console.log("กำลังจะเริ่มเปลี่ยนหน้า...");
    },
    onEnter: (el, done) => {
      // ใช้ GSAP หรือ library อื่นๆ สำหรับ animation
      gsap.from(el, {
        opacity: 0,
        y: 50,
        duration: 0.5,
        onComplete: done,
      });
    },
    onAfterEnter: () => {
      console.log("เปลี่ยนหน้าเสร็จสิ้น");
    },
  },
});
</script>

View Transitions API (ทดลองใช้)

เปิดใช้งาน View Transitions API ใน nuxt.config.ts:

typescript
export default defineNuxtConfig({
  experimental: {
    viewTransition: true,
  },
});

ตัวอย่างการใช้งาน View Transitions

vue
<template>
  <div class="image-grid">
    <NuxtLink
      v-for="item in items"
      :key="item.id"
      :to="`/items/${item.id}`"
      class="item"
      :style="{ viewTransitionName: `item-${item.id}` }"
    >
      <img :src="item.image" :alt="item.title">
    </NuxtLink>
  </div>
</template>

<style>
/* กำหนดการเคลื่อนไหวสำหรับ View Transition */
::view-transition-old(root) {
  animation: fade-out 0.3s ease-in-out;
}

::view-transition-new(root) {
  animation: fade-in 0.3s ease-in-out;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* สไตล์เพิ่มเติม */
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
  padding: 1rem;
}

.item img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.2s;
}

.item:hover img {
  transform: scale(1.03);
}
</style>

ปิดการใช้งาน Transitions

1. ปิดการใช้งานทั้งแอป

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

2. ปิดการใช้งานเฉพาะหน้า

vue
<script setup>
definePageMeta({
  pageTransition: false,
  layoutTransition: false,
});
</script>

สรุป

  • ใช้ pageTransition สำหรับการเปลี่ยนระหว่างหน้า
  • ใช้ layoutTransition สำหรับการเปลี่ยนระหว่างเลย์เอาต์
  • กำหนดค่าเริ่มต้นใน nuxt.config.ts และสามารถทับค่าในแต่ละหน้าได้
  • ใช้ JavaScript Hooks สำหรับเอฟเฟกต์พิเศษ
  • ลองใช้ View Transitions API สำหรับเอฟเฟกต์ขั้นสูง

TIP

  • ใช้ mode: 'out-in' เพื่อให้หน้าเก่าจางออกก่อนแล้วค่อยแสดงหน้าใหม่
  • ระวังการใช้งาน transition ที่ใช้ทรัพยากรสูงบนอุปกรณ์มือถือ
  • ทดสอบการทำงานบนเบราว์เซอร์ที่หลากหลาย