Nuxt.js 入门指南:从零开始构建你的第一个服务端渲染应用

130 阅读5分钟

Nuxt.js 入门指南:从零开始构建你的第一个服务端渲染应用

2025年,服务端渲染(SSR)依然是构建高性能Web应用的关键技术。本文将带你全面了解Nuxt.js框架,从基础概念到实战开发,助你快速上手这一强大的Vue.js SSR框架。

什么是Nuxt.js?

Nuxt.js 是一个基于 Vue.js 的开源框架,用于构建服务端渲染(SSR) 应用和静态站点。它简化了SSR应用的开发流程,提供了许多开箱即用的功能,如自动路由生成、代码分割、静态站点生成等。

核心特性

  • 基于Vue.js:完全兼容Vue.js生态系统,Vue开发者可以无缝过渡。
  • 服务端渲染:提供更好的SEO支持和首屏加载速度。
  • 自动代码分割:优化应用加载性能。
  • 强大的配置能力:提供默认配置的同时支持高度自定义。
  • 静态站点生成:支持将应用预渲染为静态HTML文件。

安装与项目创建

环境准备

在开始之前,确保你的系统已安装:

  • Node.js 18.x 或更高版本(推荐LTS版本)
  • 文本编辑器 如 VS Code(推荐安装 Vue 官方扩展)或 WebStorm
  • 终端 用于运行命令

创建新项目

使用以下命令快速创建Nuxt.js项目:

# 使用 npx(npm 5.2.0+ 自带)
npx create-nuxt-app <项目名>

# 或使用 yarn
yarn create nuxt-app <项目名>

# 或使用 pnpm
pnpm create nuxt-app <项目名>

# 或使用 bun
bun create nuxt-app <项目名>

执行命令后,CLI会交互式地让你选择项目配置:

  • UI框架:Bootstrap、Vuetify、Element UI等
  • 测试框架:Jest、AVA或不选择
  • Nuxt模式:Universal (SSR) 或 SPA
  • 额外模块:如Axios(HTTP请求)、ESLint(代码规范)、Prettier(代码格式化)等

手动创建项目

如果不使用脚手架,也可以手动创建Nuxt项目:

# 创建项目目录
mkdir my-nuxt-project
cd my-nuxt-project

# 初始化npm项目
npm init -y

# 安装Nuxt
npm install nuxt

# 创建pages目录
mkdir pages

然后创建package.json文件,添加以下脚本:

{
  "name": "my-nuxt-app",
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start"
  },
  "dependencies": {
    "nuxt": "^2.15.0"
  }
}

创建第一个页面文件pages/index.vue

<template>
  <div>
    <h1>Hello Nuxt.js!</h1>
  </div>
</template>

启动开发服务器

完成项目创建后,启动开发服务器:

# 进入项目目录
cd my-nuxt-project

# 启动开发服务器
npm run dev

# 或直接打开浏览器
npm run dev -- -o

应用将在 http://localhost:3000 上运行。

项目结构解析

Nuxt.js采用约定优于配置的原则,通过特定的目录结构简化开发:

my-nuxt-project/
├── assets/          # 静态资源(Webpack处理)
├── components/      # Vue组件
├── layouts/         # 布局组件
├── pages/           # 页面组件(自动生成路由)
├── plugins/         # 插件
├── static/          # 静态文件(直接服务)
├── store/           # Vuex状态管理
├── .nuxt/           # 自动生成(运行时文件)
├── nuxt.config.js   # 配置文件
└── package.json     # 项目依赖

核心目录说明

  • pages目录:最重要的目录,每个.vue文件自动生成对应的路由
  • layouts目录:包含应用的布局组件,如头部、底部导航等
  • components目录:存放可复用的Vue组件
  • static目录:存放直接服务的静态文件,如favicon.icorobots.txt

页面与路由

Nuxt.js基于文件系统自动生成路由,无需手动配置。

基础路由

pages目录下创建.vue文件即可自动生成对应路由:

pages/
--| index.vue       -> /
--| about.vue       -> /about
--| products.vue    -> /products

动态路由

创建以下划线(_)开头的文件或目录来定义动态路由:

pages/
--| users/
-----| _id.vue      -> /users/:id
--| _slug.vue       -> /:slug

在组件中,可以通过$route.params访问参数:

<template>
  <div>
    <h1>User ID: {{ $route.params.id }}</h1>
  </div>
</template>

嵌套路由

创建与父页面同名的目录来存放子视图组件,并在父组件中使用<nuxt-child/>

pages/
--| users/
-----| index.vue    -> /users
-----| _id.vue      -> /users/:id

父组件中需要添加<nuxt-child/>来显示子视图内容。

布局系统

Nuxt.js使用布局系统来管理应用的公共部分,如页眉、页脚和导航。

默认布局

创建layouts/default.vue作为默认布局:

<template>
  <div>
    <header>
      <h1>My Website</h1>
      <nav>
        <nuxt-link to="/">Home</nuxt-link>
        <nuxt-link to="/about">About</nuxt-link>
      </nav>
    </header>
    <main>
      <nuxt/> <!-- 页面内容将在这里渲染 -->
    </main>
    <footer>
      <p>&copy; 2025 My Website</p>
    </footer>
  </div>
</template>

自定义布局

创建layouts/custom.vue

<template>
  <div>
    <h1>Custom Layout</h1>
    <nuxt/>
  </div>
</template>

在页面中使用自定义布局:

<template>
  <div>This page uses a custom layout</div>
</template>

<script>
export default {
  layout: 'custom'
}
</script>

数据获取

Nuxt.js提供了多种数据获取方式,支持服务端和客户端渲染。

asyncData方法

asyncData在服务端渲染前调用,获取的数据会合并到组件数据中:

<template>
  <div>
    <h1>{{ pageTitle }}</h1>
    <ul>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    const posts = await $axios.$get('https://api.example.com/posts')
    return {
      pageTitle: 'Blog Posts',
      posts
    }
  }
}
</script>

fetch方法

fetch方法用于在渲染页面之前填充状态存储:

<script>
export default {
  async fetch({ store, params }) {
    await store.dispatch('getProduct', params.id)
  }
}
</script>

状态管理(Vuex)

Nuxt.js内置了Vuex状态管理支持。创建store/index.js文件即可启用Vuex:

// store/index.js
export const state = () => ({
  counter: 0
})

export const mutations = {
  increment(state) {
    state.counter++
  }
}

export const actions = {
  async incrementAsync({ commit }) {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 1000))
    commit('increment')
  }
}

在组件中使用:

<template>
  <div>
    <p>Counter: {{ $store.state.counter }}</p>
    <button @click="$store.commit('increment')">Increment</button>
    <button @click="$store.dispatch('incrementAsync')">Increment Async</button>
  </div>
</template>

插件系统

Nuxt.js允许使用插件来扩展功能,插件在Vue应用实例化前运行。

创建插件

创建plugins/my-plugin.js

// plugins/my-plugin.js
export default ({ app }, inject) => {
  // 注入函数
  inject('myHelper', (msg) => {
    return `Hello ${msg}!`
  })
  
  // 注入变量
  inject('version', '1.0.0')
}

注册插件

nuxt.config.js中注册插件:

// nuxt.config.js
export default {
  plugins: [
    '~/plugins/my-plugin.js'
  ]
}

使用插件

在组件中使用注入的函数或变量:

<script>
export default {
  mounted() {
    console.log(this.$myHelper('World')) // 输出: Hello World!
    console.log(this.$version) // 输出: 1.0.0
  }
}
</script>

配置管理

Nuxt.js通过nuxt.config.js文件进行配置:

基本配置

// nuxt.config.js
export default {
  // 应用元信息
  head: {
    title: 'My Nuxt App',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'My awesome Nuxt.js app' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  
  // 全局CSS
  css: [
    '~/assets/css/main.css'
  ],
  
  // 插件
  plugins: [
    '~/plugins/axios.js'
  ],
  
  // 模块
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  
  // 构建配置
  build: {
    extend(config, ctx) {
      // 自定义webpack配置
    }
  },
  
  // 服务器配置
  server: {
    port: 3000,
    host: 'localhost'
  }
}

配置代理解决跨域

安装代理模块:

npm install @nuxtjs/proxy --save-dev

配置nuxt.config.js

// nuxt.config.js
export default {
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  
  axios: {
    proxy: true,
    prefix: '/api/',
    credentials: true
  },
  
  proxy: {
    '/api/': {
      target: 'http://api.example.com',
      pathRewrite: {
        '^/api/': '/'
      },
      changeOrigin: true
    }
  }
}

样式处理

全局样式

assets目录中创建样式文件,然后在nuxt.config.js中引入:

// nuxt.config.js
export default {
  css: [
    '~/assets/css/main.css',
    '~/assets/css/animations.css'
  ]
}

CSS预处理器

安装Less支持:

npm install less less-loader@7.0.0 --save-dev

在组件中使用:

<style scoped lang="less">
@primary-color: #4fc08d;

.container {
  color: @primary-color;
  .content {
    padding: 20px;
  }
}
</style>

重置样式

创建static/reset.css文件,然后在nuxt.config.js中引入:

// nuxt.config.js
export default {
  head: {
    link: [
      { rel: 'stylesheet', href: '/reset.css' }
    ]
  }
}

部署与发布

构建应用

# 构建生产版本
npm run build

# 构建并启动生产服务器
npm run build
npm start

静态站点生成

Nuxt.js支持生成完全静态的站点:

# 生成静态文件
npm run generate

这会在dist目录中生成所有静态文件,可以直接部署到任何静态文件托管服务。

服务器部署

对于服务端渲染应用,可以使用以下方式部署:

  1. 传统服务器:将项目文件上传到服务器,安装依赖并运行npm run build && npm start
  2. Docker容器:创建Dockerfile容器化应用
  3. 云平台:部署到Vercel、Netlify、Heroku等云平台

实战示例:创建一个博客首页

下面是一个简单的博客首页示例:

<template>
  <div class="container">
    <header>
      <h1>My Blog</h1>
      <nav>
        <nuxt-link to="/">Home</nuxt-link>
        <nuxt-link to="/about">About</nuxt-link>
        <nuxt-link to="/contact">Contact</nuxt-link>
      </nav>
    </header>
    
    <main>
      <article v-for="post in posts" :key="post.id" class="post">
        <h2>{{ post.title }}</h2>
        <p>{{ post.excerpt }}</p>
        <nuxt-link :to="'/posts/' + post.slug">Read more</nuxt-link>
      </article>
    </main>
    
    <footer>
      <p>&copy; 2025 My Blog</p>
    </footer>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    const posts = await $axios.$get('/api/posts')
    return { posts }
  },
  
  head() {
    return {
      title: 'My Blog - Home',
      meta: [
        { hid: 'description', name: 'description', content: 'Welcome to my blog' }
      ]
    }
  }
}
</script>

<style>
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.post {
  margin-bottom: 40px;
  padding-bottom: 20px;
  border-bottom: 1px solid #eee;
}

footer {
  margin-top: 60px;
  text-align: center;
  color: #888;
}
</style>

总结

Nuxt.js是一个功能强大且灵活的框架,它极大地简化了Vue.js服务端渲染应用的开发流程。通过本文的介绍,你应该对Nuxt.js的核心概念和基本用法有了初步了解。

学习建议

  1. 掌握基础:熟悉Vue.js是学习Nuxt.js的前提
  2. 理解SSR原理:了解服务端渲染的工作原理和优势
  3. 实践项目:通过实际项目练习,巩固所学知识
  4. 探索生态:学习常用的Nuxt模块和插件,如@nuxtjs/axios、@nuxtjs/auth等

资源推荐

  • 官方文档nuxtjs.org/
  • 社区:GitHub Discussions、Discord频道
  • 示例项目:Nuxt.js官方示例和 starter 模板

Nuxt.js有着丰富的特性和强大的生态系统,能够帮助你构建高性能的现代Web应用。祝你学习愉快!