Gensics

Back to Home

Nuxt 3: Full-Stack Vue Framework

Nuxt Developer16 ธันวาคม 2567Nuxt
VueNuxtSSRFull-StackMeta Framework

Nuxt 3 เป็น meta-framework สำหรับ Vue 3 ที่ให้ความสามารถในการสร้าง full-stack applications ด้วยฟีเจอร์ที่ครบครัน

การติดตั้งและเริ่มต้น

# Create new Nuxt 3 project npx nuxi@latest init my-nuxt-app cd my-nuxt-app npm install npm run dev

File-based Routing

pages/
├── index.vue          # /
├── about.vue          # /about
├── blog/
│   ├── index.vue      # /blog
│   └── [slug].vue     # /blog/:slug
└── user/
    └── [id]/
        └── profile.vue # /user/:id/profile
<!-- pages/blog/[slug].vue --> <template> <div> <h1>{{ post.title }}</h1> <p>{{ post.content }}</p> </div> </template> <script setup> const route = useRoute() const { data: post } = await $fetch(`/api/posts/${route.params.slug}`) </script>

Server API Routes

// server/api/posts.get.js export default defineEventHandler(async (event) => { // Get all posts return await $fetch('https://jsonplaceholder.typicode.com/posts') }) // server/api/posts/[id].get.js export default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id') return await $fetch(`https://jsonplaceholder.typicode.com/posts/${id}`) }) // server/api/posts.post.js export default defineEventHandler(async (event) => { const body = await readBody(event) // Validate request if (!body.title || !body.content) { throw createError({ statusCode: 400, statusMessage: 'Title and content are required' }) } // Create post const post = await createPost(body) return post })

Data Fetching

<template> <div> <h1>Users</h1> <div v-if="pending">Loading...</div> <div v-else> <div v-for="user in users" :key="user.id"> {{ user.name }} </div> </div> <button @click="refresh()">Refresh</button> </div> </template> <script setup> // useFetch - auto-imports และ SSR-friendly const { data: users, pending, error, refresh } = await useFetch('/api/users') // useLazyFetch - non-blocking const { data: posts } = await useLazyFetch('/api/posts') // $fetch - สำหรับ client-side calls const createUser = async (userData) => { return await $fetch('/api/users', { method: 'POST', body: userData }) } </script>

Middleware

// middleware/auth.js export default defineNuxtRouteMiddleware((to, from) => { const user = useAuthUser() if (!user.value) { return navigateTo('/login') } }) // middleware/admin.global.js - Global middleware export default defineNuxtRouteMiddleware((to) => { if (to.path.startsWith('/admin')) { const user = useAuthUser() if (!user.value?.isAdmin) { throw createError({ statusCode: 403, statusMessage: 'Access Denied' }) } } })
<!-- pages/dashboard.vue --> <template> <div> <h1>Dashboard</h1> <!-- Only accessible by authenticated users --> </div> </template> <script setup> definePageMeta({ middleware: 'auth' }) </script>

Layouts

<!-- layouts/default.vue --> <template> <div> <header> <nav> <NuxtLink to="/">Home</NuxtLink> <NuxtLink to="/about">About</NuxtLink> <NuxtLink to="/blog">Blog</NuxtLink> </nav> </header> <main> <slot /> </main> <footer> <p>&copy; 2024 My Nuxt App</p> </footer> </div> </template> <!-- layouts/admin.vue --> <template> <div class="admin-layout"> <aside class="sidebar"> <AdminSidebar /> </aside> <main class="content"> <slot /> </main> </div> </template>

Composables

// composables/useAuth.js export const useAuth = () => { const user = useState('auth.user', () => null) const login = async (credentials) => { try { const response = await $fetch('/api/auth/login', { method: 'POST', body: credentials }) user.value = response.user await navigateTo('/dashboard') } catch (error) { throw createError({ statusCode: error.statusCode, statusMessage: error.statusMessage }) } } const logout = async () => { await $fetch('/api/auth/logout', { method: 'POST' }) user.value = null await navigateTo('/login') } const checkAuth = async () => { try { const response = await $fetch('/api/auth/me') user.value = response.user } catch (error) { user.value = null } } return { user: readonly(user), login, logout, checkAuth } }

Plugins

// plugins/api.client.js export default defineNuxtPlugin(() => { const { $fetch } = useNuxtApp() // Add auth token to requests $fetch.defaults.onRequest = ({ request, options }) => { const token = useCookie('auth-token') if (token.value) { options.headers = { ...options.headers, Authorization: `Bearer ${token.value}` } } } // Handle errors globally $fetch.defaults.onResponseError = ({ response }) => { if (response.status === 401) { return navigateTo('/login') } } })

SEO และ Meta Tags

<template> <div> <h1>{{ post.title }}</h1> <p>{{ post.content }}</p> </div> </template> <script setup> const route = useRoute() const { data: post } = await $fetch(`/api/posts/${route.params.slug}`) // SEO meta tags useHead({ title: post.title, meta: [ { name: 'description', content: post.excerpt }, { property: 'og:title', content: post.title }, { property: 'og:description', content: post.excerpt }, { property: 'og:image', content: post.image }, { name: 'twitter:card', content: 'summary_large_image' } ] }) // Structured data useJsonld({ '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, description: post.excerpt, author: { '@type': 'Person', name: post.author }, datePublished: post.createdAt }) </script>

Deployment

// nuxt.config.ts export default defineNuxtConfig({ // SSR (default) ssr: true, // SPA ssr: false, // Static Site Generation nitro: { prerender: { routes: ['/sitemap.xml'] } }, // ISR (Incremental Static Regeneration) routeRules: { '/': { prerender: true }, '/blog/**': { isr: true }, '/admin/**': { ssr: false }, '/api/**': { cors: true } } })

Environment Configuration

// nuxt.config.ts export default defineNuxtConfig({ runtimeConfig: { // Private keys (server-side only) apiSecret: '123', // Public keys (client-side) public: { apiBase: '/api' } } }) // Usage const config = useRuntimeConfig() console.log(config.public.apiBase) // Available on client console.log(config.apiSecret) // Server-side only

ข้อดีของ Nuxt 3

  • Auto-imports - ไม่ต้อง import composables และ utilities
  • File-based Routing - สร้าง routes จากโครงสร้าง files
  • SSR/SPA/SSG - รองรับ rendering modes หลากหลาย
  • API Routes - สร้าง backend API ใน framework เดียวกัน
  • SEO-friendly - Built-in SEO optimization
  • TypeScript - First-class TypeScript support
  • Performance - Optimized build และ runtime

สรุป

Nuxt 3 เป็น framework ที่ครบครันสำหรับการสร้าง Vue applications ทั้งแบบ SSR, SPA, และ SSG พร้อมด้วยฟีเจอร์ modern ที่ช่วยให้การพัฒนาเป็นไปอย่างรวดเร็วและมีประสิทธิภาพ