創建Nuxt.js項目
首先,確保你已經安裝了Node.js和yarn或npm。然後,通過命令行創建一個新的Nuxt.js項目:
yarn create nuxt-app my-nuxt-project
cd my-nuxt-project
在創建過程中,你可以選擇是否需要UI框架、預處理器等選項,根據需要配置。
目錄結構
Nuxt.js遵循特定的目錄結構,其中一些關鍵目錄如下:
├── .nuxt/ # 自動生成的文件,包含編譯後的代碼和配置
├── assets/ # 用於存放未編譯的靜態資源,如CSS、圖片、字體
├── components/ # 自定義Vue組件
├── layouts/ # 應用的佈局文件,定義頁面的通用結構
│ └── default.vue # 默認佈局
├── middleware/ # 中間件文件
├── pages/ # 應用的路由和視圖,每個文件對應一個路由
│ ├── index.vue # 默認首頁
│ └── [slug].vue # 動態路由示例
├── plugins/ # 自定義Vue.js插件
├── static/ # 靜態資源,會被原樣複製到輸出目錄
├── store/ # Vuex狀態管理文件
│ ├── actions.js # Vuex actions
│ ├── mutations.js # Vuex mutations
│ ├── getters.js # Vuex getters
│ └── index.js # Vuex store入口文件
├── nuxt.config.js # Nuxt.js配置文件
├── package.json # 項目依賴和腳本
└── yarn.lock # 或者npm.lock,記錄依賴版本
.nuxt/:這個目錄是自動生成的,包含了編譯後的代碼,一般不需要直接修改。assets/:存放未編譯的靜態資源,比如CSS、JavaScript和圖片。在構建時,Nuxt.js會處理這些資源。components/:存儲自定義Vue組件,可以複用在應用的不同部分。layouts/:定義頁面的佈局,可以有一個默認佈局,也可以有多個特定佈局。pages/:每個文件對應一個路由,文件名就是路由名稱。動態路由使用方括號[]表示。middleware/:放置自定義的中間件,可以在頁面渲染前後執行邏輯。plugins/:自定義Vue.js插件的入口文件。static/:直接複製到構建輸出目錄,不做任何處理,常用於存放robots.txt或favicon.ico等。store/:Vuex狀態管理的目錄,存放actions、mutations、getters和整個store的入口文件。nuxt.config.js:Nuxt.js的配置文件,用於定製項目的設置。package.json:項目依賴和腳本配置。yarn.lock或npm.lock:記錄項目依賴的精確版本,確保不同環境下的依賴一致性。
頁面渲染
在pages/目錄下創建一個index.vue文件,這是應用的首頁:
<!-- pages/index.vue -->
<template>
<div>
<h1>Hello from Nuxt.js SSR</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'This content is server-rendered!'
};
},
asyncData() {
// 這裏可以在服務器端獲取數據
// 返回的數據會作為data的默認值
return { message: 'Data fetched on server' };
}
};
</script>
Nuxt.js 頁面渲染的過程分為兩個主要階段:服務器端渲染 (SSR) 和客户端渲染 (CSR)。以下是Nuxt.js頁面渲染的詳細步驟:
初始化:
用户在瀏覽器中輸入URL併發送請求到服務器。
服務器接收到請求後,開始處理。
路由解析:
Nuxt.js 使用 nuxt.config.js 中的 routes 配置(如果存在)或自動從 pages/ 目錄生成路由。
對應的頁面文件被識別,例如 pages/index.vue 或 pages/about.vue。
數據預取:
Nuxt.js 查找頁面組件中的 asyncData 或 fetch 方法(如果存在)。
這些方法會在服務器端運行,用於從API或其他數據源獲取數據。
數據獲取後,會被序列化並注入到頁面模板中。
模板渲染:
Nuxt.js 使用 Vue.js 的渲染引擎將組件和預取的數據轉換為HTML字符串。
HTML字符串中包含了客户端需要的所有初始數據,以JSON格式內聯在<script>標籤中。
返回HTML:
服務器將生成的HTML響應發送回客户端(瀏覽器)。
客户端初始化:
瀏覽器接收到HTML後,開始解析和執行內聯的JavaScript。
Nuxt.js客户端庫(nuxt.js)被加載並初始化。
客户端渲染:
客户端庫接管渲染,Vue.js實例被創建,數據從內聯的JSON注入到Vue實例。
頁面完成初始渲染,用户可以看到完整的頁面內容。
此時,頁面是交互式的,用户可以觸發事件和導航。
後續導航:
當用户導航到其他頁面時,Nuxt.js 使用客户端路由(Vue Router)進行無刷新跳轉。
如果新頁面需要數據,asyncData 或 fetch 方法會在客户端運行,獲取新的數據並更新視圖。
SSG(靜態站點生成):
在開發之外,可以使用 nuxt generate 命令生成靜態HTML文件。
每個頁面都會被預渲染為獨立的HTML文件,其中包含所有必要的數據和資源。
使用asyncData
asyncData方法是Nuxt.js特有的,它允許你在服務器端預取數據並在客户端複用這些數據。在上面的示例中,我們簡單地更改了message的值,但在實際應用中,你可能會在這裏調用API獲取數據。
中間件
中間件(Middleware)是一種功能,允許你在路由變更前後執行特定的邏輯。中間件可以全局、頁面級或佈局級使用,以處理諸如認證、數據預加載、路由守衞等任務。
1. 全局中間件
全局中間件是在nuxt.config.js文件中配置的,影響應用中的所有頁面:
// nuxt.config.js
export default {
// ...
router: {
middleware: ['globalMiddleware1', 'globalMiddleware2'] // 可以是字符串數組
}
};
中間件文件通常位於middleware/目錄下,例如middleware/globalMiddleware1.js:
javascript
// middleware/globalMiddleware1.js
export default function (context) {
// context 包含 req, res, redirect, app, route, store 等信息
console.log('Global Middleware 1 executed');
}
2. 頁面級中間件
頁面級中間件隻影響特定的頁面。在頁面組件中聲明中間件:
// pages/about.vue
export default {
middleware: 'pageMiddleware' // 可以是字符串或函數
};
對應的中間件文件位於middleware/目錄,例如middleware/pageMiddleware.js:
javascript
// middleware/pageMiddleware.js
export default function (context) {
console.log('Page Middleware executed');
}
3. 佈局級中間件
佈局級中間件類似於頁面級,但作用於使用該佈局的所有頁面。在佈局組件中聲明中間件:
// layouts/default.vue
export default {
middleware: ['layoutMiddleware1', 'layoutMiddleware2']
};
對應的中間件文件位於middleware/目錄:
javascript
// middleware/layoutMiddleware1.js
export default function (context) {
console.log('Layout Middleware 1 executed');
}
// middleware/layoutMiddleware2.js
export default function (context) {
console.log('Layout Middleware 2 executed');
}
中間件的上下文(Context)
中間件函數接收一個上下文對象作為參數,該對象包含以下屬性:
req(HTTP請求對象,僅在服務器端有效)res(HTTP響應對象,僅在服務器端有效)redirect(用於重定向的函數)app(Vue實例)route(當前路由信息)store(Vuex Store,如果已啓用)payload(如果有asyncData返回的數據)
中間件可以順序執行,每個中間件可以決定是否繼續執行鏈中的下一個中間件,或者通過redirect函數中斷路由。
動態路由
Nuxt.js支持動態路由,這對於處理如博客文章、用户資料等具有動態ID的內容非常有用。在pages/目錄下創建一個動態路由文件,如[id].vue:
<!-- pages/post/[id].vue -->
<template>
<div>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
</div>
</template>
<script>
export default {
async asyncData({ params, $axios }) {
const response = await $axios.$get(`/api/posts/${params.id}`);
return { post: response.post };
}
};
</script>
這裏的[id]表示動態參數,asyncData會自動處理這個參數並獲取對應ID的博客文章。
佈局
佈局允許你定義全局或特定頁面的通用結構。在layouts/目錄下創建一個default.vue文件:
<!-- layouts/default.vue -->
<template>
<div>
<header>
<nav>
<!-- 導航鏈接等 -->
</nav>
</header>
<main>
<nuxt /> <!-- 這裏將插入頁面內容 -->
</main>
<footer>
<!-- 底部信息等 -->
</footer>
</div>
</template>
默認情況下,所有頁面都將使用此佈局。如果你想為特定頁面設置不同的佈局,可以在頁面組件中指定:
// pages/about.vue
export default {
layout: 'custom' // 在layouts/下創建custom.vue
};
插件與庫集成
Nuxt.js支持Vue.js的插件,你可以在nuxt.config.js中配置:
javascript
// nuxt.config.js
export default {
plugins: [
{ src: '~plugins/vuetify.js', ssr: true },
{ src: '~plugins/vue-chartjs.js', mode: 'client' } // 僅在客户端運行
]
};
然後在plugins/目錄下創建相應的文件,如vuetify.js:
// plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);
配置與優化
Nuxt.js 配置文件(nuxt.config.js)
nuxt.config.js 是Nuxt應用的主要配置文件,用於定製化應用的行為。以下是一些常用的配置項:
- 模式(mode):設置應用的運行模式,可選值有 'spa'(單頁面應用)、'universal'(服務端渲染)和 'static'(靜態生成)。默認為 'universal'。
- head:配置頁面的 <head> 部分,如標題、元數據、鏈接等。
- css:指定全局CSS文件,可以是文件路徑數組。
- build:配置構建過程,如transpile、extractCSS、extend等。例如,可以在這裏添加Babel插件或調整Webpack配置。
- router:自定義路由配置,如base路徑、模式等。
- axios:配置axios模塊,包括基礎URL、代理設置等。
- plugins:註冊全局Vue插件,可以指定在客户端或服務器端加載。
- modules:加載外部模塊,如@nuxtjs/axios、@nuxtjs/proxy等。
- env:定義環境變量,這些變量將在構建時注入到客户端和服務器端。
// nuxt.config.js
export default {
// 項目名稱
name: 'my-nuxt-app',
// 項目模式:spa, universal, static
mode: 'universal', // 默認值,支持服務器端渲染
// 應用元信息
head: {
title: 'My Nuxt App',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'App description' }
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
// CSS樣式
css: [
'@/assets/css/main.css'
],
// 路由配置
router: {
base: '/my-nuxt-app/', // 應用的基礎路徑
extendRoutes(routes, resolve) {
// 手動擴展或修改路由
}
},
// 構建配置
build: {
transpile: [/^my-vue-component/], // 需要轉譯的模塊
vendor: ['lodash'], // 公共庫,提前打包
extractCSS: true, // 提取CSS到單獨文件
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
filename: 'vendors.js'
}
}
}
}
},
// Axios配置
axios: {
baseURL: process.env.BASE_URL || 'http://localhost:3000/api', // API基礎URL
browserBaseURL: 'https://api.example.com' // 客户端的API基礎URL
},
// Plugins
plugins: [
{ src: '@/plugins/vue-my-plugin', ssr: false } // 異步加載的插件,ssr: false 表示僅客户端加載
],
// Modules
modules: [
'@nuxtjs/axios', // 安裝並配置axios模塊
'@nuxtjs/pwa' // 安裝並配置PWA模塊
],
// 環境變量
env: {
apiKey: 'your-api-key',
apiUrl: 'https://api.example.com'
},
// Vuex Store配置
store: true, // 自動創建Vuex store
loading: { color: '#3B8070' }, // 加載指示器顏色
// 服務端中間件
serverMiddleware: [
{ path: '/api', handler: '~/api/index.js' } // 使用自定義的服務器端中間件
],
// 靜態生成配置
generate: {
dir: 'dist', // 輸出目錄
fallback: true, // 對未預渲染的動態路由生成404頁面
routes: () => ['/about', '/contact'] // 預渲染的指定路由
}
};
優化策略
- 異步數據預取(asyncData/fetch):利用asyncData或fetch方法在服務器端預取數據,減少客户端渲染的負擔。
- 代碼拆分:Nuxt.js自動進行代碼拆分,確保只有當路由被訪問時才加載相關代碼。
- 靜態站點生成(SSG):使用nuxt generate命令生成靜態HTML文件,適用於內容不頻繁變動的站點,提高加載速度和SEO友好性。
- 緩存策略:利用HTTP緩存策略,如ETag、Last-Modified,減少重複請求。
- Vue.js優化:確保Vue組件的優化,如避免無用的watcher、使用v-once減少重新渲染等。
- 圖片優化:使用正確的圖片格式(如WebP),並確保圖片尺寸適當,使用懶加載技術。
- Service Worker:集成PWA支持,使用Service Worker進行離線緩存和推送通知。
- Tree Shaking:確保你的依賴庫支持Tree Shaking,以剔除未使用的代碼。
- 分析與監控:使用nuxt build --analyze或集成第三方工具(如Google Lighthouse)進行性能分析,持續監控應用性能。
靜態站點生成(SSG)
Nuxt.js 的靜態站點生成(Static Site Generation, SSG)是通過 nuxt generate 命令實現的。這個命令會遍歷應用的路由,為每個路由生成一個預渲染的 HTML 文件,這些文件可以直接部署到任何靜態文件託管服務上。以下是關於SSG的一些關鍵點:
1. 配置: 在 nuxt.config.js 文件中,可以配置 generate 選項來控制靜態生成的行為:
export default {
generate: {
dir: 'dist', // 輸出目錄,默認為dist
fallback: true, // 對未預渲染的動態路由生成404頁面
routes: () => ['/about', '/contact'], // 預定義的靜態路由
exclude: ['/admin/*'], // 排除某些路由
interval: 5000, // 生成間隔,單位毫秒
concurrency: 10 // 併發生成的路由數量
}
}
2. 生成: 運行 npm run generate 或 yarn generate 來啓動靜態生成過程。Nuxt.js 會根據 generate.routes 裏的配置生成對應的 HTML 文件。如果沒有顯式定義,它會自動掃描 pages/ 目錄下的所有文件來生成路由。
3. 數據預取: 在頁面組件中,可以使用 asyncData 或 fetch 方法來預取數據。這些數據會在生成靜態頁面時被注入到 HTML 中,使頁面在客户端加載時無需額外請求:
// pages/about.vue
export default {
async asyncData({ params, $axios }) {
const aboutInfo = await $axios.$get('/api/about')
return { aboutInfo }
}
}
4. 中間件處理:服務器端的中間件不會在SSG過程中執行,因為SSG是在沒有服務器環境的情況下生成靜態文件。所以,如果需要在生成時執行某些邏輯,最好在 asyncData 或 fetch 中處理。
5. 部署: 生成的靜態文件可以部署到任何靜態文件託管服務,如 Netlify、Vercel、GitHub Pages 或 AWS S3。這些服務通常不需要運行任何服務器端代碼,只需上傳生成的 dist 文件夾即可。
6. SEO 優化: SSG 提高了SEO,因為搜索引擎爬蟲可以讀取預渲染的 HTML 內容,而無需等待JavaScript執行。
7. 動態路由: 對於動態路由,Nuxt.js 會嘗試生成所有可能的組合。如果無法預測所有可能的動態路由,可以手動在 generate.routes 中指定,或者使用 generate.includePaths 和 generate.excludePaths 來控制。
8. 404 頁面: 設置 generate.fallback 為 true 會為未預渲染的動態路由生成一個404頁面,當用户訪問這些路由時,Nuxt.js 會嘗試在客户端渲染它們。
運行nuxt generate命令,Nuxt.js將生成靜態HTML文件。
驗證和錯誤處理
驗證(Validation)
驗證通常涉及表單數據或API請求的輸入驗證。Nuxt.js本身不直接提供驗證庫,但你可以集成像Vuelidate、vee-validate這樣的第三方庫,或者使用TypeScript等進行類型檢查。
使用Vee-Validate
1. 安裝: 首先,你需要安裝vee-validate庫:
npm install vee-validate
2. 配置: 在nuxt.config.js中添加Vue插件配置:
export default {
plugins: [{ src: '~/plugins/vee-validate', ssr: false }]
};
3. 創建插件: 在plugins/vee-validate.js中配置Vee-Validate:
import Vue from 'vue';
import VeeValidate from 'vee-validate';
Vue.use(VeeValidate);
4. 使用: 在你的組件中使用Vee-Validate進行表單驗證:
<template>
<form @submit.prevent="submitForm">
<input v-model="email" name="email" v-validate="'required|email'"/>
<span>{{ errors.first('email') }}</span>
<button type="submit">Submit</button>
</form>
</template>
<script>
export default {
data() {
return {
email: ''
};
},
methods: {
submitForm() {
this.$validator.validateAll().then(result => {
if (result) {
// 驗證成功邏輯
} else {
// 驗證失敗邏輯
}
});
}
}
};
</script>
錯誤處理
Nuxt.js提供了幾種處理錯誤的方法,包括全局錯誤處理和頁面特定的錯誤處理。
全局錯誤處理
- 自定義錯誤頁面: 在layouts目錄下創建error.vue文件,用於自定義錯誤頁面佈局。
- 捕獲全局錯誤: 在nuxt.config.js中配置error屬性來捕獲全局錯誤:
export default {
error: {
// 頁面不存在時的處理
pageNotFound({ error, store, app, env }) {
// 處理邏輯
},
// 任何錯誤的處理
handler(error, { error: nuxtError, store, app, env }) {
// 處理邏輯
}
}
};
頁面特定錯誤處理
在頁面組件中,可以使用asyncData或fetch方法的try-catch結構來處理錯誤:
export default {
async asyncData({ params, error }) {
try {
const data = await fetchSomeData(params.id);
return { data };
} catch (err) {
error({ statusCode: 500, message: '數據獲取失敗' });
}
}
};
API請求錯誤處理
對於API請求,如果你使用了@nuxtjs/axios模塊,可以在請求攔截器中統一處理錯誤:
// plugins/axios.js
import axios from 'axios';
import { toast } from '~/utils/toast';
axios.interceptors.response.use(null, (error) => {
const { status } = error.response;
if (status === 401) {
// 處理未授權錯誤
} else if (status >= 500) {
// 處理服務器錯誤
toast.error('服務器錯誤');
}
return Promise.reject(error);
});
export default ({ $axios }, inject) => {
inject('axios', $axios);
};
確保在nuxt.config.js中註冊此插件。
Vue生態系統集成
Vue Router:
Nuxt.js 自動為你的應用生成了一個基於文件結構的路由系統。路由配置通常不需要手動編寫,但可以通過 nuxt.config.js 的 router 屬性進行擴展。
Vuex:
Nuxt.js 自動創建了一個 Vuex store。在 store 目錄下,你可以創建模塊化的 state、mutations、actions 和 getters。例如,創建一個 store/modules/users.js 文件來管理用户數據。
// store/modules/users.js
export const state = () => ({
users: []
});
export const mutations = {
SET_USERS(state, payload) {
state.users = payload;
}
};
export const actions = {
async fetchUsers({ commit }) {
const response = await this.$axios.get('/api/users');
commit('SET_USERS', response.data);
}
};
Vue CLI:
Nuxt.js 提供了自己的構建工具,但它也基於 Vue CLI。這意味着你可以使用類似 Vue CLI 的命令行工具,如 npx nuxt generate(靜態生成)或 npx nuxt build(構建應用)。
Babel:
Nuxt.js 默認配置了 Babel,以便支持最新的 JavaScript 特性。你通常不需要手動配置 Babel,除非有特殊需求。
TypeScript:
若要使用 TypeScript,設置 typescript: true 在 nuxt.config.js 中,Nuxt.js 會自動配置 TypeScript 支持。
ESLint:
為了代碼質量檢查,可以在項目中安裝 ESLint 並配置 .eslintrc.js。Nuxt.js 提供了 @nuxt/eslint-module 插件來簡化集成。
// nuxt.config.js
module.exports = {
buildModules: [
'@nuxt/typescript-build',
'@nuxtjs/eslint-module' // 添加 ESLint 集成
],
eslint: {
fix: true, // 自動修復錯誤
ignoreDuringBuilds: true // 忽略構建期間的錯誤
}
};
VueUse:
VueUse 是一個包含各種實用功能的 Vue 用例庫。要集成,首先安裝 @vueuse/core,然後在組件中導入並使用功能。
npm install @vueuse/core
// 在組件中
import { useCounter } from '@vueuse/core';
export default {
setup() {
const count = useCounter(0); // 使用計數器功能
// ...
}
};
Vue插件:
可以通過 nuxt.config.js 的 plugins 配置項來全局註冊 Vue 插件。例如,集成 Vue Toastify 用於顯示通知:
// nuxt.config.js
export default {
plugins: [{ src: '~plugins/toastify.js', ssr: false }]
};
// plugins/toastify.js
import Vue from 'vue';
import Toastify from 'toastify-js';
Vue.use(Toastify);
使用Nuxt.js工作流
Nuxt.js提供了開發、構建和部署的完整工作流。使用nuxt命令啓動開發服務器,nuxt build進行生產構建,nuxt start啓動生產服務器,nuxt generate生成靜態文件。
性能優化
- 靜態生成(SSG): 使用 nuxt generate 命令生成預渲染的HTML文件,這可以大大提高首屏加載速度,對SEO友好。
- 代碼分割: Nuxt.js 默認會進行代碼分割,將應用分為多個小塊,只加載當前頁面需要的代碼,減少了初始加載的體積。
- 延遲加載(Lazy Loading): 對於大型應用,可以考慮延遲加載組件或模塊,只在需要時加載。可以使用<nuxt-child :lazy="true">或<component :is="...">結合async組件來實現。
- 優化資源:
- 圖片:使用正確的格式(如WebP),壓縮圖片,使用懶加載(<img :src="..." :loading="lazy">),或者使用nuxt-image或nuxt-picture組件。
- CSS:提取CSS到單獨文件,減少內聯樣式。
- JS:利用Tree Shaking剔除未使用的代碼。
- 異步數據預取: 使用 asyncData 或 fetch 方法預加載數據,確保數據在渲染之前已經準備好。
- 服務端緩存: 使用 nuxt-ssr-cache 模塊來緩存服務器端渲染的結果,減少不必要的API調用。
- HTTP緩存: 設置正確的緩存頭(如Cache-Control),利用瀏覽器緩存靜態資源。
- 路由守衞: 使用 beforeRouteEnter 等路由守衞,避免在不需要時加載數據。
- 減少HTTP請求: 合併多個CSS和JS文件,減少HTTP請求數量。
- 優化API性能: 優化後端接口,減少響應時間,使用分頁、過濾和緩存策略。
- 利用CDN: 將靜態資源託管在CDN上,加快全球用户的加載速度。
- 優化Vuex狀態管理: 避免不必要的計算屬性和監聽器,減少狀態改變的開銷。
- 性能審計: 使用Lighthouse、Chrome DevTools或其他性能審計工具定期檢查應用性能,並根據報告進行改進。
- Service Worker: 如果適用,集成PWA特性,利用Service Worker進行離線緩存和資源預加載。
- 模塊優化: 選擇性能高效的第三方模塊,並確保它們已經針對SSR進行了優化。
2500G計算機入門到高級架構師開發資料超級大禮包免費送!