Nuxt.js Fundamental ตอนที่ 3 - การกำหนด Routing

Published on

เขียนวันที่ : Aug 22, 2020

LastModified on

(อัพเดท : Mar 19, 2022)

Discord

ก่อนหน้านี้ใน ตอนที่ 1 เราจะเห็นได้ว่า เราสามารถสร้างหน้า Pages ง่ายๆ ด้วยการสร้างไฟล์ *.vue ไว้ในโฟลเดอร์ pages เท่านั้น ก็ได้หน้าใหม่แล้ว

โดยปกติถ้าเราเขียน Vue.js ธรรมดา เราก็จะใช้ vue-router กันใช่มั้ยครับ และก็มีไฟล์ router.js ตัวนึง ในการจัดการ routes ทั้งหมดใน Application ของเรา

แต่ใน Nuxt.js มันจะ auto generate ตัว Vue Router ให้เราเลย เช่น ถ้าไฟล์ในโฟลเดอร์ pages เรามีประมาณนี้

pages/
--| auth/
-----| login.vue
-----| register.vue
--| index.vue
--| dashboard.vue

ตัว Nuxt.js มันก็จะ Generate Router ให้เราเป็นแบบนี้เลย

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'dashboard',
      path: '/dashboard',
      component: 'pages/dashboard.vue'
    },
    {
      name: 'auth-login',
      path: '/auth/login',
      component: 'pages/auth/index.vue'
    },
    {
      name: 'auth-register',
      path: '/auth/register',
      component: 'pages/auth/one.vue'
    }
  ];
}

Dynamic Routes

นอกจากการ generate route แบบ static page แล้ว ตัว Nuxt.js ก็รองรับการ auto generate เป็นแบบ Dynamic Route ด้วยนะครับ

โดยการใส่ underscore (_) ข้างหน้าชื่อไฟล์ *.vue หรือชื่อ folder ของเราครับ เช่น เรามีไฟล์แบบนี้

pages/
--| _posts/
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

ตัว Nuxt.js ก็จะ generate ให้เราเป็นแบบนี้ครับ

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'users-id',
      path: '/users/:id?',
      component: 'pages/users/_id.vue'
    },
    {
      name: 'slug',
      path: '/posts/:slug',
      component: 'pages/posts/_slug/index.vue'
    }
  ];
}

สิ่งที่เพื่อนๆ จะเห็นความแตกต่างคือ ตรง users-id ทำให้ path เป็น /users/:id? ซึ่งเป็น optional ครับ ถ้าเราจะให้มันเป็น required เลย เราต้องสร้าง /users/_id ให้เป็น folder ครับ แล้วข้างในมีไฟล์ index.vue ครับ

ข้อสังเกตง่ายๆ
  • Optional - ใช้ underscore ข้างหน้าชื่อไฟล์
  • Required - ใช้ underscore ข้างหน้าชื่อโฟลเดอร์ และข้างในมีไฟล์ index.vue ครับ

การ Navigate ระหว่าง Page เราจะใช้ component ชื่อ NuxtLink ครับ (เหมือนกับการใช้ <RouterLink> ใน Vue.js ปกติเลยครับ)

โดย syntac ก็จะเหมือน HTML tag <a> เลยครับ เพียงแค่เปลี่ยนจาก href="" เป็น to="" เท่านั้น เช่น

<template>
  <NuxtLink to="/">Home page</NuxtLink>
</template>

เราใช้ <NuxtLink to="/another-page"> กรณีที่เราต้องการเปลี่ยนหน้าระหว่าง Page ของเว็บเรา แต่ถ้าเป็นเว็บภายนอก เราก็ใช้ <a> ปกติครับ

Route Params

ใน Nuxt.js เราสามารถที่จะเข้าถึงค่า params จาก Dynamic Router โดยใช้

this.$route.params.<NAME>

// เช่น
this.$route.params.id

สังเกตว่า $route.params.id ไม่ต้องมี underscore (_) เหมือนชื่อไฟล์ หรือ folder นะครับ

และเราสามารถที่จะ validate เพื่อดังค่า หรือใส่ logic ได้ ด้วย function ที่ชื่อว่า validate() ดังนี้ครับ

export default { validate({ params }) { // Must be a number return /^\d+$/.test(params.id) } }

หาก ค่าใน validate ไม่ได้คืนค่าเป็น true หรือ Promise.resolve(true) ตัว Nuxt.js จะทำการโหลดหน้า 404 Page ให้อัตโนมัติครับ

ตัว validate() จะ execute 1 ครั้ง ฝั่ง server side และ client side กรณีที่ navigate มาที่หน้า route ที่เรากำหนด

อ่านเพิ่มเติม

Hints & Questions?

  • เพื่อนๆลองส่งค่า <nuxt-link to="/"> ที่มากกว่าแค่ string ลองส่งเป็น Object ดูครับ ว่าทำอะไรได้บ้าง?
  • ลองประยุกค์ใช้ validate() ว่ามันมีประโยชน์ยังไง?
  • ทำ Routing แบบ nested route ซ้อนกัน มี parent มี child ได้มั้ยนะ?
  • ใน route เราอยากกำหนดพวกค่า เช่น meta: {requiredAuth: true} แบบ Vuex Router ได้มั้ย?
Buy Me A Coffee
Discord