NuxtJS 学习笔记

NuxtJS 学习笔记

一、NuxtJS 是什么?

NuxtJS 是基于 Vue.js 的开源框架,专为构建高性能、SEO 友好的现代 Web 应用设计。它集成了 Vue 生态的核心工具(Vue RouterVuex/PiniaVue 编译器等),并提供了服务端渲染(SSR)、**静态站点生成(SSG)**等关键能力,解决了纯 Vue 单页应用(SPA)首屏加载慢、SEO 不友好的痛点。

核心定位

  • 不是替代 Vue,而是 增强 Vue 的“上层框架”
  • 专注于“应用工程化”,简化 Vue 项目的配置、构建、部署流程
  • 支持多渲染模式:SSR(服务端渲染)、SSG(静态生成)、CSR(客户端渲染)、ISR(增量静态再生)

二、NuxtJS 核心特点

1. 开箱即用的渲染方案

  • SSR(服务端渲染):页面在服务端渲染成 HTML 后再返回客户端,首屏加载快、SEO 友好
  • SSG(静态生成):构建时预渲染所有页面为静态 HTML,部署到 CDN 即可,性能极致
  • 自动切换:无需手动配置复杂的渲染逻辑,Nuxt 内部优化渲染流程

2. 零配置路由系统

  • 基于文件系统的路由:pages/ 目录下的 .vue 文件自动生成路由(无需手动写 Vue Router 配置)
  • 支持动态路由(如 pages/user/[id].vue)、嵌套路由、路由守卫(middleware/ 目录)

3. 内置优化与配置

  • 自动代码分割、Tree-shaking,减少打包体积
  • 内置 CSS 预处理支持(Sass/SCSS、Less 等,无需额外装 loader)
  • 自动处理静态资源(图片、字体等),支持自动优化图片尺寸和格式
  • 内置 ESLint、Prettier 配置,规范代码风格

4. 强大的 SEO 支持

  • 服务端渲染输出完整 HTML,搜索引擎可直接抓取内容
  • 内置 head 配置(标题、元标签、OG 标签),可在页面或全局统一设置
  • 支持 JSON-LD 结构化数据,提升 SEO 排名

5. 模块生态丰富

  • 官方模块:Pinia(状态管理)、I18n(国际化)、Auth(身份认证)、Content(内容管理)等
  • 第三方模块:支持集成 Tailwind CSSElement PlusAxios 等常用工具

6. 开发体验友好

  • 热模块替换(HMR):修改代码实时更新,无需刷新页面
  • 错误页面自动生成:404、500 等页面可自定义
  • 内置调试工具,支持 VS Code 语法提示

三、NuxtJS 安装步骤

前提条件

  • Node.js 版本 ≥ 18.x(Nuxt 3 最低要求,推荐 18.x LTS 或 20.x LTS)
  • 包管理器:npm、yarn 或 pnpm(推荐 npm 或 pnpm)

推荐安装方式(Nuxt 3,官方首选)

Nuxt 3 推荐使用 nuxi 命令行工具(官方维护,稳定无网络坑):

  1. 检查 Node 版本

    node -v  # 输出 v18.x 或更高版本
    
  2. 创建项目(指定项目名,如 nuxt-demo

    npx nuxi init nuxt-demo
    
  3. 进入项目目录

    cd nuxt-demo
    
  4. 安装依赖

    npm install  # 或 yarn install、pnpm install
    
  5. 启动开发服务器

    npm run dev  # 启动后访问 http://localhost:3000
    

兼容安装(Nuxt 2,旧项目使用)

若需兼容 Nuxt 2,使用 create-nuxt-app(需解决网络问题,参考前文):

# 安装并创建 Nuxt 2 项目
npx create-nuxt-app@2 nuxt2-demo

安装常见问题解决

  1. 网络超时/模板下载失败:
    • 切换 npm 镜像源:npm config set registry https://registry.npmmirror.com
    • 修改 Hosts 映射 raw.githubusercontent.com(参考前文方案二)
  2. 依赖安装失败:
    • 清除 npm 缓存:npm cache clean --force
    • 升级包管理器:npm install -g npm@latest

四、NuxtJS 基础使用

1. 项目目录结构(Nuxt 3 核心目录)

nuxt-demo/
├── app.vue          # 根组件(入口文件)
├── pages/           # 页面目录(自动生成路由)
│   ├── index.vue    # 首页(对应 / 路由)
│   └── about.vue    # 关于页(对应 /about 路由)
├── components/      # 公共组件目录(自动导入,无需 import)
├── composables/     # 组合式函数目录(自动导入)
├── nuxt.config.ts   # Nuxt 配置文件(核心配置)
└── package.json     # 依赖配置

2. 核心功能使用示例

(1)页面与路由(自动路由)

Nuxt 最核心的特性之一,无需配置 Vue Router,文件即路由:

  • pages/index.vue → 路由 /(首页)
  • pages/about.vue → 路由 /about(关于页)
  • pages/user/[id].vue → 动态路由 /user/123(通过 $route.params.id 获取参数)

页面组件示例(pages/index.vue)

<template>
  <div class="container">
    <h1>Hello Nuxt 3!</h1>
    <!-- 路由跳转(使用 NuxtLink,类似 Vue Router 的 router-link) -->
    <NuxtLink to="/about">前往关于页</NuxtLink>
  </div>
</template>

<script setup>
// 无需导入 NuxtLink,Nuxt 自动全局注册
</script>

<style scoped>
.container {
  padding: 2rem;
  text-align: center;
}
</style>
(2)组件使用(自动导入)

components/ 目录下的组件无需手动 import,直接在页面中使用:

  1. 创建组件:components/HelloWorld.vue

    <template>
      <p>这是公共组件:{{ msg }}</p>
    </template>
    
    <script setup>
    const props = defineProps({
      msg: String
    })
    </script>
    
  2. 在页面中使用(pages/index.vue):

    <template>
      <div class="container">
        <h1>Hello Nuxt 3!</h1>
        <HelloWorld msg="Nuxt 组件自动导入真方便~" />
      </div>
    </template>
    
(3)数据请求(内置 useFetch)

Nuxt 3 内置 useFetch 组合式函数,支持服务端/客户端数据请求(自动处理 SSR/SSG 数据预取):

<!-- pages/users.vue -->
<template>
  <div>
    <h2>用户列表</h2>
    <ul v-if="users.length">
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
    <p v-else>加载中...</p>
  </div>
</template>

<script setup>
// 服务端预取数据,页面渲染时已包含数据(SEO 友好)
const { data: users } = await useFetch('https://jsonplaceholder.typicode.com/users')
</script>
(4)全局配置(nuxt.config.ts)

核心配置文件,用于配置路由、CSS、模块、服务器等:

// nuxt.config.ts
export default defineNuxtConfig({
  // 应用基础配置
  app: {
    head: {
      title: '我的 Nuxt 应用', // 全局页面标题
      meta: [
        { name: 'description', content: 'NuxtJS 学习笔记示例' } // SEO 描述
      ]
    }
  },
  // 全局 CSS(无需在组件中导入)
  css: ['~/assets/css/global.css'],
  // 模块配置(如集成 Tailwind CSS)
  modules: ['@nuxtjs/tailwindcss']
})
(5)状态管理(Pinia,Nuxt 3 推荐)
  1. 安装 Pinia 模块:

    npm install @pinia/nuxt
    
  2. nuxt.config.ts 中注册:

    export default defineNuxtConfig({
      modules: ['@pinia/nuxt']
    })
    
  3. 创建 Store:stores/counter.ts

    import { defineStore } from 'pinia'
    
    export const useCounterStore = defineStore('counter', {
      state: () => ({ count: 0 }),
      actions: {
        increment() {
          this.count++
        }
      }
    })
    
  4. 在页面中使用:

    <template>
      <div>
        <p>计数:{{ counter.count }}</p>
        <button @click="counter.increment()">+1</button>
      </div>
    </template>
    
    <script setup>
    const counter = useCounterStore()
    </script>
    

3. 运行与构建命令

命令作用
npm run dev启动开发服务器(热更新,默认 3000 端口)
npm run build构建生产版本(根据配置生成 SSR/SSG 资源)
npm run preview预览构建后的生产版本
npm run generate生成静态站点(SSG,输出 dist/ 目录)

五、获取MySQL数据

5.1 安装 MySQL 依赖

yarn add mysql2 -S

5.2 封装数据库连接(复用 + 连接池)

在项目根目录创建 server/utils/db.js(Nuxt 服务端工具目录),封装数据库连接池(避免频繁创建连接):

// server/utils/db.js
import mysql from 'mysql2/promise';

// 数据库配置(请替换为你的 MySQL 地址、账号、密码)
const DB_CONFIG = {
  host: 'localhost', // 本地 MySQL 默认为 localhost,远程需填服务器 IP
  user: 'root',      // 你的 MySQL 用户名(默认 root)
  password: '123456',// 你的 MySQL 密码(安装时设置的密码)
  database: 'nuxt_echart_db', // 第一步创建的数据库名
  port: 3306,        // MySQL 默认端口 3306
  waitForConnections: true,
  connectionLimit: 10, // 最大连接数
  queueLimit: 0
};

// 创建连接池
const pool = mysql.createPool(DB_CONFIG);

// 封装查询方法(全局复用)
export async function query(sql, params = []) {
  const [rows] = await pool.execute(sql, params);
  return rows;
}

5.3 开发 Nuxt API 接口(服务端)

Nuxt 4 内置 API 路由(无需额外配置服务器),在 server/api 目录下创建接口文件,用于查询 MySQL 数据并返回给前端。

创建接口文件:server/api/line-chart-data.get.js

// server/api/line-chart-data.get.js
// 接口地址:http://localhost:3000/api/line-chart-data(GET 请求)
import { query } from '../utils/db';

export default defineEventHandler(async (event) => {
  try {
    // 查询所有数据(按时间排序,确保 x 轴顺序正确)
    const sql = 'SELECT date, golden_lake, supply_chain, unknown_vuln, malicious_code, copyright, crowdsourced, trusted_repair FROM echart_line_data ORDER BY date ASC';
    const data = await query(sql);

    // 整理数据格式(适配前端 ECharts 配置)
    const result = {
      xAxisData: data.map(item => item.date), // x 轴时间数据
      seriesData: [
        { name: '金银湖大模型漏洞检测', data: data.map(item => item.golden_lake) },
        { name: '供应链漏洞检测', data: data.map(item => item.supply_chain) },
        { name: '未知漏洞检测', data: data.map(item => item.unknown_vuln) },
        { name: '恶意代码投毒检测', data: data.map(item => item.malicious_code) },
        { name: '代码版权检测', data: data.map(item => item.copyright) },
        { name: '众测漏洞检测', data: data.map(item => item.crowdsourced) },
        { name: '可信修复', data: data.map(item => item.trusted_repair) }
      ]
    };

    // 返回数据给前端(200 成功状态)
    return {
      code: 200,
      message: '数据获取成功',
      data: result
    };
  } catch (error) {
    // 错误处理(打印日志 + 返回错误信息)
    console.error('接口错误:', error);
    return {
      code: 500,
      message: '数据获取失败',
      error: error.message
    };
  }
});

测试接口是否可用

  • 启动 Nuxt 项目:yarn dev;
  • 浏览器访问:http://localhost:3000/api/line-chart-data
  • 若返回如下 JSON,说明接口正常(数据与 SQL 插入的一致):
{
  "code": 200,
  "message": "数据获取成功",
  "data": {
    "xAxisData": ["24.09","24.10","24.11","24.12","25.01","25.02","25.03"],
    "seriesData": [
      {"name":"金银湖大模型漏洞检测","data":[310,190,360,400,410,300,220]},
      // 其他 6 个系列数据...
    ]
  }
}

六、Axios全局注册

6.1 安装axios

# 安装 Axios(Nuxt 4 兼容所有最新版本)
yarn add axios -S

6.2 全局注册 Axios(客户端插件)

app/plugins/ 目录下创建 axios.client.ts.client 后缀确保仅客户端使用,避免服务端报错),全局配置 Axios 并提供给所有组件:

// app/plugins/axios.client.ts
import { defineNuxtPlugin } from "#app";
import axios from "axios";

export default defineNuxtPlugin((nuxtApp) => {
  // 1. 创建 Axios 实例,配置基础路径、超时等(按需调整)
  const axiosInstance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || "http://localhost:3000", // 基础路径(可通过环境变量配置)
    timeout: 5000, // 超时时间(5秒)
    headers: {
      "Content-Type": "application/json", // 默认请求头
    },
  });

  // 2. 可选:添加请求拦截器(如添加 Token、统一请求参数)
  axiosInstance.interceptors.request.use(
    (config) => {
      // 示例:添加登录 Token(从 localStorage 读取,按需修改)
      const token = localStorage.getItem("token");
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    },
    (error) => Promise.reject(error)
  );

  // 3. 可选:添加响应拦截器(统一处理错误、解析数据)
  axiosInstance.interceptors.response.use(
    (response) => {
      // 直接返回响应体(Axios 已自动解析 JSON),无需手动 json()
      return response.data;
    },
    (error) => {
      // 统一错误处理(如 401 未授权、500 服务器错误)
      console.error("Axios 请求失败:", error.message);
      return Promise.reject(error);
    }
  );

  // 4. 全局提供 Axios 实例:组件中可通过 this.$axios 或 useNuxtApp() 获取
  nuxtApp.provide("axios", axiosInstance);
});
  • baseURL 配置:默认指向你的 Nuxt 服务端接口地址(http://localhost:3000),后续调用接口可省略基础路径(如 /api/line-chart-data 直接写成 api/line-chart-data);
  • 拦截器:可选但推荐添加,统一处理 Token、错误,减少组件内重复代码;
  • 全局提供:通过 nuxtApp.provide("axios", instance),组件中可全局访问,无需局部导入。

6.3组件中调用 Axios(全局使用)

<!-- app/components/EchartsLine.client.vue -->
<template>
  <div ref="chartRef" class="chart-container"></div>
</template>

<script>
import * as echarts from "echarts";

export default {
  name: "EchartsLine",
  data() {
    return {
      chartRef: null,
      chartData: null, // 存储接口返回数据
    };
  },
  mounted() {
    this.fetchChartData(); // 组件挂载时请求数据
  },
  methods: {
    // 调用 Axios 获取接口数据
    async fetchChartData() {
      try {
        // 全局调用 Axios(无需导入,直接 this.$axios)
        const res = await this.$axios.get("api/line-chart-data"); // 省略 baseURL,直接写相对路径

        // 直接使用解析后的数据(Axios 已自动处理 JSON)
        if (res.code === 200) {
          this.chartData = res.data;
          this.initECharts(); // 初始化 ECharts
        } else {
          console.error("数据获取失败:", res.message);
        }
      } catch (error) {
        console.error("接口请求失败:", error.message);
      }
    },
    // 初始化 ECharts
    initECharts() {
      if (!this.chartRef || !this.chartData) return;
      const chart = echarts.init(this.chartRef);
      // ECharts 配置项(使用 this.chartData)
      const option = {
        title: { text: "折线图示例", color: "#CEF4FD" },
        xAxis: {
          type: "category",
          data: this.chartData.xData, // 接口返回的 x 轴数据
          axisLine: { lineStyle: { color: "#CEF4FD" } },
          axisLabel: { color: "#CEF4FD" },
        },
        yAxis: {
          type: "value",
          axisLine: { lineStyle: { color: "#CEF4FD" } },
          axisLabel: { color: "#CEF4FD" },
        },
        series: [
          {
            data: this.chartData.seriesData, // 接口返回的系列数据
            type: "line",
            lineStyle: { color: "#6dd0e3" },
            itemStyle: { color: "#6dd0e3" },
          },
        ],
        backgroundColor: "transparent",
      };
      chart.setOption(option);
      // 窗口resize自适应
      window.addEventListener("resize", () => chart.resize());
    },
  },
};
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 400px;
}
</style>

七、Nuxt 应用部署服务器

入口点

使用 Node 服务器预设运行 nuxt build 时,结果将是一个可直接运行的 Node 服务器入口点。

node .output/server/index.mjs

这将启动您的生产 Nuxt 服务器,默认监听 3000 端口。

它支持以下运行时环境变量:

  • NITRO_PORTPORT(默认为 3000)
  • NITRO_HOSTHOST(默认为 ‘0.0.0.0’)
  • NITRO_SSL_CERTNITRO_SSL_KEY - 如果两者都存在,将以 HTTPS 模式启动服务器。在绝大多数情况下,除了测试外不应使用此选项,并且 Nitro 服务器应在终止 SSL 的反向代理(如 nginx 或 Cloudflare)后面运行。

PM2

PM2(进程管理器 2)是在您的服务器或虚拟机上托管 Nuxt 应用程序的快速简便解决方案。

要使用 pm2,请在跟目录创建并使用 ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'NuxtAppName',
      port: '3000',
      exec_mode: 'cluster',
      instances: 'max',
      script: './.output/server/index.mjs'
    }
  ]
}

将以下文件 / 文件夹上传到服务器的 /www/nuxt3-project 目录(用 Xftp 或 scp 命令):

  • .output/(Nuxt3 打包产物,核心);
  • ecosystem.config.js(PM2 配置文件);
  • .env(可选,环境变量配置,优先级低于 PM2 的 env);
  • logs/(日志文件夹)。
# 1.PM2 启动服务(读取 ecosystem.config.cjs 配置)
pm2 start

# 2. 验证服务状态(关键!确保启动成功)
pm2 list

// 后续命令
pm2 restart Nuxt3-App  # 重启服务(更新代码/配置后用)
pm2 stop Nuxt3-App     # 停止服务
pm2 logs Nuxt3-App     # 查看实时日志(排查错误)
pm2 delete Nuxt3-App   # 删除服务
pm2 save               # 保存当前 PM2 配置(服务器重启后自动恢复)
pm2 startup            # 设置 PM2 开机自启(服务器重启后自动启动服务)

集群模式

您可以使用 NITRO_PRESET=node_cluster 来利用 Node.js cluster 模块实现多进程性能。
默认情况下,工作负载会以轮询策略分配给工作进程。

静态托管

将 Nuxt 应用程序部署到任何静态托管服务有两种方式:

  • 使用 ssr: true 的静态站点生成 (SSG) 在构建时预渲染应用程序的路由。(这是运行 nuxt generate 时的默认行为。)它还将生成 /200.html 和 /404.html 单页应用回退页面,这些页面可以在客户端渲染动态路由或 404 错误(尽管您可能需要在静态主机上配置此功能)。
  • 或者,您可以使用 ssr: false 预渲染您的站点(静态单页应用)。这将生成包含空 <div id="__nuxt"></div> 的 HTML 页面,您的 Vue 应用通常会在此处渲染。这样会失去预渲染站点的许多 SEO 优势,因此建议改用 <ClientOnly> 来包装站点中无法在服务器端渲染的部分(如果有的话)。
仅客户端渲染

如果您不想预渲染路由,另一种使用静态托管的方法是在 nuxt.config 文件中将 ssr 属性设置为 false。然后,nuxt generate 命令将输出一个 .output/public/index.html 入口点和 JavaScript 捆绑包,就像经典的客户端 Vue.js 应用程序一样。

// nuxt.config.ts
export default defineNuxtConfig({
  ssr: false
})
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值