在現代前端開發的領域中,Vue.js 以其簡潔、易學和高效的特性,贏得了廣大開發者的青睞。然而,當我們面對需要優化 SEO(搜尋引擎優化)、提升首頁載入速度或建構更複雜的全端應用時,僅僅使用 Vue 的客戶端渲染(CSR)模式可能會遇到瓶頸。為此,Nuxt 3 應運而生。
Nuxt 3 是一個基於vue.js的開源框架,它不僅繼承了 vue3 的所有優點,更將其提升到一個新的層次。它旨在讓全端 Web 開發變得直觀且高效,提供卓越的開發者體驗。本篇文章將深入探討 Nuxt 3 的核心價值,從其與 nuxt.js 的根本差異、專案的從零到一建置、強大的路由系統,到資料獲取與樣式設定,為您提供一份詳盡且深入的學習指南與學習筆記。
核心概念:為何選擇 Nuxt 3?
要理解 Nuxt 的價值,我們必須先從網頁渲染的兩種主要模式談起:客戶端渲染(CSR)與伺服器端渲染(SSR)。
SPA (CSR) vs. MPA (SSR)
傳統的 Vue.js 應用程式大多是單頁應用程式(Single Page Application, SPA),採用的是**客戶端渲染(Client-Side Rendering, CSR)**模式。
- 運作方式:瀏覽器首次載入時,只會得到一個近乎空白的 HTML 檔案和一堆 JavaScript 文件。接著,瀏覽器執行 JavaScript,動態生成網頁內容並渲染出來。後續的頁面切換也由 JavaScript 在前端完成,無需重新向伺服器請求整個頁面。
- 優點:頁面切換流暢,使用者體驗極佳,伺服器負擔較小。
- 缺點:
- SEO 表現不佳:搜尋引擎爬蟲抓取到的初始 HTML 內容是空的,不利於內容索引,可能導致搜尋排名不佳。
- 首次內容繪製(FCP)較慢:使用者需要等待所有 JavaScript 下載並執行完畢後才能看到頁面內容,在網路環境不佳或專案龐大時,白畫面時間會很長。
相對地,傳統的網站是多頁應用程式(Multi Page Application, MPA),採用伺服器端渲染(Server-Side Rendering, SSR),也就是所謂的 server side render。
- 運作方式:每次請求頁面,伺服器都會處理邏輯、查詢資料,然後將一個渲染完成的、包含完整內容的 HTML 檔案傳送給瀏覽器。
- 優點:
- SEO 友好:爬蟲可以直接抓取到完整的 HTML 內容。
- 首頁載入速度快:瀏覽器接收到 HTML 後能立即顯示內容。
- 缺點:每次換頁都需要重新請求,伺服器負擔較重,使用者體驗不如 SPA 流暢。
Nuxt 的解決方案:通用渲染 (Universal Rendering)
Nuxt 巧妙地結合了兩者的優點,預設採用通用渲染模式(Universal Rendering)。
- 首次載入 (SSR):當使用者或爬蟲第一次訪問網站時,Nuxt 會在伺服器端執行 vue3 程式碼,渲染出完整的 HTML 頁面後再回傳給瀏覽器。這確保了快速的 FCP 和優良的 SEO。
- 客戶端接管 (Hydration):瀏覽器接收到 HTML 後,會下載 JavaScript 檔案。待 JS 載入完成後,Vue 會「接管」由伺服器產生的靜態 DOM,並為其附加事件監聽器,使其變為具備互動性的動態頁面。這個過程被稱為Hydration(脫水/激活)。
- 後續導航 (CSR):一旦 Hydration 完成,整個應用程式就變成了一個 SPA。後續的所有頁面切換都在客戶端完成,保留了流暢的使用者體驗。
特性比較 | 客戶端渲染 (CSR) – Vue SPA | 伺服器端渲染 (SSR) – Nuxt |
---|---|---|
SEO 表現 | 較差,需額外配置才能改善 | 極佳,原生支援 |
首頁載入速度 | 較慢,需等待 JS 執行 | 較快,HTML 直出 |
使用者體驗 | 頁面切換流暢,互動性強 | 首次載入後,體驗與 SPA 無異 |
伺服器負擔 | 較低 | 較高,需執行渲染 |
開發複雜度 | 相對簡單 | 需考慮伺服器端環境 |
專案建立與環境設定
開始使用 Nuxt 3 非常簡單。首先,請確保您的 Node.js 版本在 v16.10.0 或以上。
初始化專案
打開您的文字編輯器如 Visual Studio Code,並在其內建的終端機執行以下指令:
npx nuxi@latest init my-nuxt3-project
這個指令會建立一個名為 my-nuxt3-project 的新資料夾,此處的 my-nuxt3-project 即為您的 \<project-name>,可以自訂。接著,進入該目錄並安裝依賴套件:
cd my-nuxt3-project
npm install
安裝完成後,執行以下指令即可啟動開發伺服器:
npm run dev -- -o
您的瀏覽器將會自動打開 http://localhost:3000,並顯示 Nuxt 的歡迎頁面。
整合 Tailwind CSS
Tailwind CSS 是現今非常流行的 CSS 框架。根據其官網的教學,在 Nuxt 3 中整合它變得極為方便。
- 安裝模組: bash npm install -D @nuxtjs/tailwindcss
- 配置 nuxt.config.ts:
將 @nuxtjs/tailwindcss 加入到 modules 陣列中。 typescript // nuxt.config.ts export default defineNuxtConfig({ devtools: { enabled: true }, modules: [ ‘@nuxtjs/tailwindcss’ ] }) - 建立 CSS 檔案:
在專案根目錄下建立 assets/css/main.css 檔案,並加入 Tailwind 的三個主要指令: css /* assets/css/main.css */ @tailwind base; @tailwind components; @tailwind utilities; Nuxt 會自動引入此檔案。現在,您就可以在專案的任何 .vue 檔案中使用 Tailwind 的 class 了。
Nuxt 3 檔案結構與路由系統
Nuxt 的一個核心特性是其「基於檔案系統的路由 (File-System Routing)」。您不需要手動撰寫任何路由設定,Nuxt 會根據 pages/ 資料夾內的檔案結構自動生成。
路由基礎
首先,在專案根目錄下建立一個名為 pages 的資料夾。
- 根路由: pages/index.vue → 會對應到網站的根路徑 /。
- 一般路由: pages/about.vue → 會對應到路徑 /about。
- 巢狀路由 (Nested Routes):
- pages/events/index.vue → 對應到 /events,此為該目錄的預設頁面。
- pages/events/profile.vue → 對應到 /events/profile。
動態路由 (Dynamic Routes)
當您需要根據參數顯示不同內容時(例如商品詳情頁),可以使用動態路由。檔案名稱以方括號 [] 包裹。
- 檔案: pages/events/[id].vue
- 路徑: 這會匹配 /events/1、/events/abc 等任何符合格式的路徑。
在頁面中,我們可以使用 useRoute() 這個組合式函數(Composable)來獲取當前的路由資訊,包括動態參數。
<script setup>
// 引用 useRoute composable
const route = useRoute();
// 從路由參數中取得 id
const eventId = route.params.id;
// 透過 console.log() 的方法,可以在主控臺查看完整的 route 物件
console.log(route);
</script>
<template>
<div>
<h1>活動詳情頁</h1>
<p>正在查看的活動 ID 是: {{ eventId }}</p>
<p>另一種方式:{{ $route.params.id }}</p>
</div>
</template>
頁面導航與渲染
- <NuxtLink>: 這是 Nuxt 提供的連結元件,相當於 Vue Router 的 <RouterLink>。請務必使用它來處理內部連結,以確保 Nuxt 能正確地進行客戶端導航。 html <NuxtLink to=”/”>首頁</NuxtLink> <NuxtLink to=”/about”>關於我們</NuxtLink>
- <NuxtPage>: 這個元件相當於 Vue Router 的 <RouterView>,它會負責渲染當前路由所對應的頁面元件。
- 佈局 (Layouts): 如果多個頁面有共同的 UI 結構(例如頁首、頁尾),您可以建立 layouts 資料夾。layouts/default.vue 會是所有頁面的預設佈局。您需要使用 <slot /> 標籤來指定頁面內容 (<NuxtPage>) 應該被渲染在哪個位置。這個<slot />標籤就是用來放置頁面主要內容的東西。 vue <template> <div> <header>這是我的網站頁首</header> <main> <slot /> </main> <footer>這是我的網站頁尾</footer> </div> </template>
資料獲取 (Data Fetching)
在 SSR 應用中,於伺服器端預先獲取資料至關重要。Nuxt 3 提供了強大的組合式函數 useFetch 來簡化這個過程。它會在伺服器端執行,獲取資料後再進行頁面渲染。
<script setup>
const apiUrl = 'https://api.example.com/products';
// useFetch 會在伺服器端和客戶端執行
// data: 響應式資料
// pending: 是否正在請求中
// error: 錯誤物件
const { data: products, pending, error } = await useFetch(apiUrl, {
// 可以傳入選項,例如 lazy: true 來延遲加載
// pick: ['id', 'title'] 來只選取需要的欄位
});
</script>
<template>
<div>
<h1>產品列表</h1>
<div v-if="pending">
載入中...
</div>
<div v-else-if="error">
發生錯誤: {{ error.message }}
</div>
<ul v-else>
<li v-for="product in products" :key="product.id">
<NuxtLink :to="`/products/${product.id}`">{{ product.title }}</NuxtLink>
</li>
</ul>
</div>
</template>
這個方法的設計完美契合了 vue3 的 <script setup> 語法,讓非同步資料的處理變得既優雅又直觀。
常見問題 (FAQ)
Q1: 學完 Vue 一定要學 Nuxt 嗎?
答:不是強制性的,但強烈推薦。如果您的專案需要優化 SEO、改善首頁載入效能,或者您想以更結構化的方式開發全端應用,Nuxt 會是您的最佳選擇。您可以透過 Nuxt 官網文件或參與坊間的線上課程來獲得更系統性的教學,它可以讓您專注於業務邏輯,而將複雜的伺服器端渲染配置交給框架處理。
Q2: Nuxt 3 和 Nuxt 2 有什麼主要差別?
答:Nuxt.js 3 是一次徹底的重寫,主要差異包括:
- 核心升級:基於 vue3 (Nuxt 2 是 Vue 2)。
- 打包工具:使用 Vite 取代 Webpack,帶來極速的開發伺服器啟動和熱模組更新。
- 伺服器引擎:採用全新的 Nitro 引擎,提供跨平臺部署能力和更佳的效能。
- API 設計:全面擁抱 Composition API,提供如 useFetch, useRoute 等組合式函數,取代了 Nuxt 2 的 Options API 風格(如 asyncData)。
- TypeScript:原生支援 TypeScript,提供更強的型別安全。
- 開發者工具:更完善的開發者工具整合,例如與 ESLint 的配置更加無痛。
Q3: Nuxt 只能做 SSR 嗎?
答:不是。Nuxt 非常靈活,支援多種渲染模式。您可以在 nuxt.config.ts 中透過 ssr: false 將整個專案切換為純客戶端渲染的 SPA 模式。此外,它還支援靜態站點生成(Static Site Generation, SSG),透過使用 nuxt generate 這個指令,可以將您的應用程式預先渲染成靜態 HTML 檔案,適合部署在任何靜態主機上。
Q4: 如何在 Nuxt 3 中管理狀態(State Management)?
答:對於跨元件的簡單狀態共享,Nuxt 3 內建了 useState 這個組合式函數。對於更複雜的全域狀態管理,官方推薦使用 Pinia。Pinia 作為 Vue 的新一代官方狀態管理庫,與 Nuxt 3 完美整合,提供了直觀、型別安全且支援伺服器端渲染的狀態管理方案。
總結
Nuxt 3 不僅僅是 Vue 的一個擴展,它是一個經過深思熟慮、功能完備的全端框架。它透過檔案系統路由、元件自動載入、強大的資料獲取機制和基於 Vite 與 Nitro 的高效能架構,極大地簡化了現代 Web 應用的開發流程。
對於任何一位 Vue 開發者來說,學習 Nuxt 3 意味著為自己的技能樹點亮了 SSR 和全端開發的關鍵技能點。無論是需要打造對 SEO 有嚴格要求的內容型網站,還是追求極致效能的複雜應用,Nuxt 3 都提供了一套堅實可靠且充滿樂趣的解決方案。