Skip to content

โครงสร้างโปรเจค Nuxt.js

โครงสร้างพื้นฐานของโปรเจค Nuxt.js ประกอบด้วยโฟลเดอร์และไฟล์ต่างๆ ดังนี้

bash
nuxt-project/
├── .nuxt/              # โฟลเดอร์สำหรับไฟล์ที่ถูกสร้างโดยอัตโนมัติระหว่าง development
├── .output/            # โฟลเดอร์สำหรับผลลัพธ์จากการ build production
├── assets/             # ไฟล์ที่ต้องผ่านการประมวลผล (CSS, SCSS, images)
├── components/         # Vue components ที่นำมาใช้ซ้ำได้
├── composables/        # Composable functions สำหรับ Composition API
├── content/            # ไฟล์เนื้อหา (Markdown, YAML, JSON) สำหรับ Nuxt Content
├── layouts/            # Layouts ของแอปพลิเคชัน
├── middleware/         # Middleware functions ที่ทำงานก่อนการ render pages
├── modules/            # Custom Nuxt modules
├── node_modules/       # Dependencies ที่ติดตั้งผ่าน npm/yarn/pnpm
├── pages/              # หน้าต่างๆ ของแอปพลิเคชัน (ใช้สร้าง routes อัตโนมัติ)
├── plugins/            # Plugins ที่ทำงานก่อน Vue instance ถูกสร้าง
├── public/             # ไฟล์ static ที่ไม่ต้องผ่านการประมวลผล (robots.txt, favicon)
├── server/             # API routes และ server middleware
├── shared/             # โค้ดที่แชร์ระหว่าง client และ server
├── utils/              # Utility functions
├── .env                # Environment variables
├── .gitignore          # ไฟล์ที่ Git ควรละเว้น
├── .nuxtignore         # ไฟล์ที่ Nuxt ควรละเว้น
├── .nuxtrc             # Configuration สำหรับ Nuxt CLI
├── app.vue             # Entry point หลักของแอปพลิเคชัน
├── app.config.ts       # Configuration runtime ของแอปพลิเคชัน
├── error.vue           # หน้า error แบบ global
├── nuxt.config.ts      # Configuration หลักของ Nuxt
├── package.json        # Dependencies และ scripts
└── tsconfig.json       # TypeScript configuration

ด้านล่างเขียนแต่ละ

.nuxt/

ts
// .nuxt/components.d.ts - ตัวอย่างไฟล์ที่ถูกสร้างอัตโนมัติ
export const components = {
  "MyComponent": defineAsyncComponent(() =>
    import("../components/MyComponent.vue")
  ),
  "TheHeader": defineAsyncComponent(() =>
    import("../components/TheHeader.vue")
  ),
};

โฟลเดอร์ที่ Nuxt สร้างขึ้นโดยอัตโนมัติระหว่างการพัฒนา (development) ประกอบด้วยไฟล์ชั่วคราวที่จำเป็นสำหรับการทำงานของแอปพลิเคชัน ไม่ควรแก้ไขไฟล์ในโฟลเดอร์นี้โดยตรง

.output/

bash
.output/
├── public/           # Static assets และ prerendered pages
├── server/           # Server-side code
└── nitro.json        # Nitro configuration

โฟลเดอร์ที่เก็บผลลัพธ์จากการ build แอปพลิเคชันสำหรับ production ซึ่งถูกสร้างขึ้นเมื่อรัน nuxt build ประกอบด้วยไฟล์ที่พร้อมสำหรับการ deploy

assets/

css
/* assets/css/main.css */
body {
  font-family: "Arial", sans-serif;
  background-color: #f5f5f5;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
}

ใช้เก็บไฟล์ที่ต้องผ่านการประมวลผลโดย build tools เช่น CSS, SASS, SCSS, รูปภาพ ไฟล์เหล่านี้จะถูก process และ optimize ในขั้นตอนการ build

components/

vue
<!-- components/Button.vue -->
<template>
  <button
    class="btn"
    :class="[`btn-${type}`, { 'btn-large': large }]"
    @click="$emit('click')"
  >
    <slot></slot>
  </button>
</template>

<script setup>
defineProps({
  type: {
    type: String,
    default: "primary",
  },
  large: {
    type: Boolean,
    default: false,
  },
});

defineEmits(["click"]);
</script>

เก็บ Vue components ที่สามารถนำมาใช้ซ้ำได้ทั่วทั้งแอปพลิเคชัน Nuxt จะทำการ auto-import components เหล่านี้โดยอัตโนมัติ

composables/

ts
// composables/useCounter.ts
export const useCounter = () => {
  const count = ref(0);

  const increment = () => count.value++;
  const decrement = () => count.value--;

  return {
    count: readonly(count),
    increment,
    decrement,
  };
};

เก็บ composable functions สำหรับ Vue Composition API ซึ่งจะถูก auto-import เช่นกัน ช่วยให้สามารถแยกและนำ logic กลับมาใช้ซ้ำได้

content/

md
<!-- content/blog/hello-world.md -->
---
title: Hello World
date: 2023-04-15
description: My first blog post
---

# Hello World

This is my first blog post using Nuxt Content.

## Features

- Markdown support
- Code highlighting
- Frontmatter

ใช้กับ Nuxt Content module เพื่อเก็บเนื้อหาในรูปแบบไฟล์ Markdown, YAML, JSON หรืออื่นๆ เหมาะสำหรับการสร้าง blog หรือเอกสาร

layouts/

vue
<!-- layouts/default.vue -->
<template>
  <div class="layout">
    <header>
      <nav>
        <NuxtLink to="/">Home</NuxtLink>
        <NuxtLink to="/about">About</NuxtLink>
        <NuxtLink to="/contact">Contact</NuxtLink>
      </nav>
    </header>

    <main>
      <slot />
    </main>

    <footer>
      <p>&copy; {{ new Date().getFullYear() }} My Nuxt App</p>
    </footer>
  </div>
</template>

เก็บ layout components ที่กำหนดโครงสร้างหลักของหน้าเว็บ สามารถสลับ layouts ได้ในแต่ละหน้า

middleware/

ts
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const user = useUser();

  // ถ้าผู้ใช้ไม่ได้ล็อกอินและพยายามเข้าถึงหน้าที่ต้องล็อกอิน
  if (!user.value && to.meta.requiresAuth) {
    return navigateTo("/login", { redirectCode: 401 });
  }
});

เก็บ middleware functions ที่ทำงานก่อนการ render pages ใช้สำหรับตรวจสอบการเข้าถึง, เปลี่ยนเส้นทาง หรือเตรียมข้อมูลก่อนแสดงหน้า

modules/

ts
// modules/example-module.ts
import { defineNuxtModule } from "@nuxt/kit";

export default defineNuxtModule({
  meta: {
    name: "example-module",
    configKey: "exampleModule",
    compatibility: { nuxt: "^3.0.0" },
  },
  defaults: {
    enabled: true,
  },
  setup(options, nuxt) {
    // ตั้งค่าต่างๆ สำหรับ module
    if (!options.enabled) return;

    // เพิ่ม plugin
    nuxt.hook("components:dirs", (dirs) => {
      dirs.push({
        path: resolve("./runtime/components"),
        prefix: "Example",
      });
    });
  },
});

ใช้สำหรับพัฒนา custom Nuxt modules เพื่อขยายความสามารถของ Nuxt framework

pages/

vue
<!-- pages/index.vue -->
<template>
  <div>
    <h1>Welcome to my Nuxt App</h1>
    <p>This is the home page</p>
    <NuxtLink to="/about">Learn more about us</NuxtLink>
  </div>
</template>

<script setup>
definePageMeta({
  layout: "default",
  title: "Home",
});
</script>

เก็บหน้าต่างๆ ของแอปพลิเคชัน โดย Nuxt จะสร้าง routes อัตโนมัติตามโครงสร้างไฟล์ในโฟลเดอร์นี้

plugins/

ts
// plugins/vue-toast.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueToast, {
    position: "top-right",
    duration: 3000,
  });

  return {
    provide: {
      toast: (message, options) => {
        // Custom toast implementation
      },
    },
  };
});

เก็บ plugins ที่ทำงานก่อน Vue instance ถูกสร้าง ใช้สำหรับการตั้งค่า global components, functions หรือ libraries

public/

public/
├── favicon.ico
├── robots.txt
└── images/
    └── logo.png

เก็บไฟล์ static ที่ไม่ต้องผ่านการประมวลผล เช่น robots.txt, favicon.ico ไฟล์เหล่านี้จะถูกคัดลอกไปยัง root ของเว็บไซต์โดยตรง

server/

ts
// server/api/users.ts
export default defineEventHandler(async (event) => {
  const users = await db.users.findMany();

  return {
    users,
    total: users.length,
  };
});

ใช้สำหรับการสร้าง API endpoints และ server middleware ประกอบด้วยโฟลเดอร์ api/ สำหรับสร้าง REST API และโฟลเดอร์ middleware/ สำหรับ server-side middleware