为什么使用 Nuxt?

像 Nuxt 这样的框架之所以存在,是因为传统的 SPA 和多页应用程序(MPA)的服务器端渲染存在不足。我们可以将 Nuxt 视为服务器端渲染 MPA 和传统 SPA 的混合体。因此,它被称为 “通用” 或 “同构”。所以,能够进行服务器端渲染是 Nuxt 的决定性特征。在本节中,我们将带你了解 Nuxt 的其他突出特性,这些特性将使你的应用程序开发变得轻松有趣。我们要介绍的第一个特性允许你通过在文件中使用 .vue 扩展名来编写单文件 Vue 组件。

编写单文件组件

我们可以使用几种方法来创建 Vue 组件。全局 Vue 组件通过使用 Vue.component 创建,如下所示:

Vue.component('todo-item', {...})

另一方面,局部 Vue 组件可以使用普通的 JavaScript 对象创建,如下所示:

const TodoItem = {...}

如果你将 Vue 用于小型项目,这两种方法都是可管理和可维护的,但是当你在一个大型项目中同时拥有大量具有不同模板、样式和 JavaScript 方法的组件时,管理起来就会变得困难。

因此,单文件组件应运而生,在单文件组件中,每个 Vue 组件我们只使用一个 .vue 文件。如果你的应用程序需要多个组件,只需将它们分成多个 .vue 文件即可。在每个文件中,你都可以编写仅与该特定组件相关的模板、脚本和样式,如下所示:

// pages/index.vue
<template>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data () {
    return { message: 'Hello World' }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

在这里,你可以看到我们如何在一个 .vue 文件中同时拥有一个 HTML 模板(用于打印来自 JavaScript 脚本的消息)和一个 CSS 样式(用于描述模板的呈现方式)。这使你的代码更结构化、更易读和更有条理。很棒,不是吗?这只有通过 vue-loader 和 webpack 才能实现。在 Nuxt 中,无论它们是 /components/、/pages/ 还是 /layouts/ 目录中的组件,我们都只在 .vue 文件中编写组件。我们将在第二章 “Nuxt 入门” 中更详细地探讨这一点。现在,我们将看看 Nuxt 的另一个特性,它允许你开箱即用地编写 ES6 JavaScript。

编写 ES2015+ 代码

Nuxt 开箱即用地编译你的 ES6+ 代码,你无需担心在 webpack 中配置和安装 Babel。这意味着你可以直接编写 ES6+ 代码,并且你的代码将被编译成可以在旧浏览器上运行的 JavaScript。例如,在使用 asyncData 方法时,你经常会看到以下解构赋值语法:

// pages/about.vue
<script>
export default {
  async asyncData ({ params, error }) {
    //...
  }
}
</script>

前面的代码中使用了析构赋值语法,将 Nuxt 上下文中的属性解包到不同的变量中,我们可以在 asyncData 方法的逻辑中使用这些变量。

有关 Nuxt 上下文和 ECMAScript 2015 功能的更多信息,请分别访问 https://nuxtjs.org/api/context 和 https://babeljs.io/docs/en/learn/ 。

在 Nuxt 中编写 ES6 只有通过 babel-loader 和 webpack 才能实现。你可以在 Nuxt 中编写的不仅仅是析构赋值语法,还包括 async 函数、await 操作符、箭头函数、import 语句等等。那么 CSS 预处理器呢?如果你使用流行的 CSS 预处理器(如 Sass、Less 或 Stylus)编写 CSS 样式,但如果你是 Sass 的拥护者而不是 Less 或 Stylus 的拥护者,Nuxt 是否支持它们中的任何一个?简短的答案是肯定的。我们将在下一节中找到这个问题的详细答案。

使用预处理器编写 CSS

在 Nuxt 中,你可以选择你最喜欢的 CSS 预处理器来编写应用程序的样式,无论是 Sass、Less 还是 Stylus。它们已经在 Nuxt 中为你预先配置好了。你可以在 https://github.com/nuxt/nuxt.js/blob/dev/packages/webpack/src/config/base.js 查看它们的配置。因此,你只需要在你的 Nuxt 项目中安装预处理器及其 webpack 加载器。例如,如果你想使用 Less 作为你的 CSS 预处理器,只需在你的 Nuxt 项目中安装以下依赖项:

$ npm i less --save-dev
$ npm i less-loader --save-dev

然后,你可以通过在 <style> 块中将 lang 属性设置为 "less" 来开始编写你的 Less 代码,如下所示:

// pages/index.vue
<template>
  <p>Hello World</p>
</template>

<style scoped lang="less">
@align: center;

p {
  text-align: @align;
}
</style>

从这个例子中,你可以看到在 Nuxt 中编写现代 CSS 样式就像编写现代 JavaScript 一样简单。你所需要做的就是安装你最喜欢的 CSS 预处理器及其 webpack 加载器。在本书接下来的章节中,我们将使用 Less,但现在,让我们了解一下 Nuxt 提供的其他功能。

有关这些预处理器及其 webpack 加载器的更多信息,请访问以下链接:

即使 PostCSS 不是预处理器,如果你想在 Nuxt 项目中使用它,请访问 https://nuxtjs.org/faq/postcss-plugins 提供的指南。

使用模块和插件扩展 Nuxt

Nuxt 基于模块化架构构建。这意味着你可以使用无数的模块和插件来扩展你的应用程序或 Nuxt 社区。这也意味着你可以从 Nuxt 和 Vue 社区选择大量的模块和插件,这样你就不必为你的应用程序重新发明轮子。以下是这些链接:

模块和插件本质上都是 JavaScript 函数。现在不必担心它们之间的区别;我们将在第六章 “编写插件和模块” 中详细介绍这一点。

添加路由之间的过渡效果

与传统的 Vue 应用程序不同,在 Nuxt 中,你无需使用 <transition> 元素来处理元素或组件上的 JavaScript 动画、CSS 动画和 CSS 过渡。例如,如果你想在导航到特定页面时应用淡入淡出效果,只需将过渡名称(例如,fade)添加到该页面的 transition 属性即可:

// pages/about.vue
<script>
export default {
  transition: {
    name: 'fade'
  }
}
</script>

然后,你只需在 .css 文件中创建过渡样式:

// assets/transitions.css
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.fade-leave,
.fade-enter-to {
  opacity: 1;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 3s;
}

当导航到 /about 路由时,“fade” 过渡将自动应用于 about 页面。很酷,不是吗?如果此时代码或类名看起来有点让人不知所措,请不要担心;我们将在第四章 “添加视图、路由和过渡效果” 中更详细地介绍和探索此过渡功能。

管理 <head> 元素

此外,与传统的 Vue 应用程序不同,你可以开箱即用地管理应用程序的 <head> 块,而无需安装处理它的额外的 Vue 包——vue-meta。你只需通过 head 属性将所需的 <title>、<meta> 和 <link> 数据添加到任何页面。例如,你可以通过应用程序的 Nuxt 配置文件管理全局 <head> 元素:

// nuxt.config.js
export default {
  head: {
    title: '我的 Nuxt 应用',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '我的 Nuxt 应用是关于...' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  }
}

Nuxt 会将这些数据转换为 HTML 标签。同样,我们将在第四章 “添加视图、路由和过渡效果” 中学习并更详细地探讨此功能。

Vue-Meta 是一个专为 Vue.js 设计的插件,用于管理 HTML 元数据(如标题、描述、关键词等),支持服务端渲染(SSR)和客户端渲染(SPA),是优化 SEO 和提升用户体验的关键工具。

使用 webpack 打包和拆分代码

Nuxt 使用 webpack 来打包、压缩并将你的代码分割成多个代码块,这可以加快你的应用加载速度。例如,在一个简单的包含两个页面(首页和关于页)的 Nuxt 应用中,你将获得类似的客户端代码块:

Hash: 0e9b10c17829e996ef30
Version: webpack 4.43.0
Time: 4913ms
Built at: 06/07/2020 21:02:26

(省略)

你将获得的服务器端代码块如下所示:

Hash: 8af8db87175486cd8e06
Version: webpack 4.43.0
Time: 525ms
Built at: 06/07/2020 21:02:27

Assets:
  - pages/about.js: 1.23 KiB 1 [emitted] (pages/about)
  - pages/index.js: 6.06 KiB 2 [emitted] (pages/index)
  - server.js: 80.9 KiB 0 [emitted] (app)
  - server.manifest.json: 291 bytes [emitted]

+ 3 hidden assets

Entrypoint app:
  - server.js
  - server.js.map

当你使用 Nuxt 的 npm run build 命令构建你的应用程序以进行部署时,会生成这些代码块和构建信息。我们将在第十四章 “使用代码检查器、格式化工具和部署命令” 中更详细地介绍这一点。

除此之外,Nuxt 还使用了 webpack 的其他强大功能和插件,例如静态文件和资源服务(资源管理)、热模块替换、CSS 提取(extract-css-chunks-webpack-plugin)、构建和监听过程中的进度条(webpackbar)等等。更多信息请访问以下链接:

webpack、Babel 和 Nuxt 本身提供的这些强大功能将使你的现代项目开发变得有趣且轻松。现在,让我们看看各种应用程序类型,以了解在构建下一个 Web 应用程序时,你是否应该使用 Nuxt。