[TOC]

前言

Nuxt.js 是一个基于 vue.js 的通用应用框架
主要是用来进行 UI 渲染,服务端渲染(SSR)
Nuxt.js 集成了以下组件/框架,用于开发完整而强大的 Web 应用:
Vue2、Vue-Router、Vuex、Vue服务端渲染(排除使用 mode: ‘spa’)、Vue-Meta

特性

  • 基于 Vue.js
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能、支持异步数据
  • 静态文件服务
  • ES2015+ 语法支持
  • 打包和压缩 JS 和 CSS
  • HTML 头部标签管理
  • 本地开发支持热加载
  • 集成 ESLint 格式规范
  • 支持各种样式预处理器:sass、less、stylus 等
  • 支持 HTTP/2 推送

    流程图

    Nuxt.js - 图1

安装

  • 初始化并创建一个 Nuxt.js 项目 ```vue 首先执行: vue init nuxt/starter

Generate project in current directory? [yes]

Project name [项目名]

Project description 回车

Author [作者名称]

```javascript
npx create-nuxt-app <项目名>

服务端渲染的好处

  1. 更好的 SEO,由于所搜引擎爬虫抓取工具可以直接查看完全渲染的页面。
  2. 对于缓慢的网络或者运行缓慢的设备,提供获取网页速度,有良好的用户体验
  3. SSR 会减少对服务器的请求。
    1. 普通页面,会先获取文件,在读取内容,读取到 ajax 的 js 时,在向服务器发送请求,获取内容,这就是至少二次对服务器的请求了
  4. SSR 直接在服务端渲染为完整的页面,发送到浏览器

Nuxt使用组件

  1. nuxt.config.js 中写入以下代码

    export default {
    components: true,
    }
    
  2. pages 目录下的组件中使用即可,无需引入 ```vue // 方法1:当组件在components根目录下时的引入方法

// 方法2:当组件在components/user目录下时的引入方法

> NuxtJS中使用组件需要注意组件的目录等级 <br /> <a name="hpcXq"></a> # 路由跳转 <a name="nVPZu"></a> ## 基础路由 1. 在NuxtJS中,只需在 `pages`目录下创建组件以及目录即可,无需自己手写路由 1. NuxtJS会自动解析 `pages`目录下的文件路径,随即生成对应的路由 1. NuxtJS中使用路由跳转的方法如下所示:vue // 跳转至 user/index.vue 目录下 > 在一个 `pages`目录下或任意子目录下创建 `index.vue` 文件,访问该目录路径,相当于直接访问了该目录下的 `index.vue` 文件 <a name="aJUHU"></a> ## 动态路由 1. 以下划线`_`为前缀的 Vue 文件或目录,都是带有参数的动态路由matlab pages/ —| slug/ ——-| comments.vue ——-| index.vue —| users/ ——-| _id.vue —| index.vue ```javascript router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'users-id', path: '/users/:id?', component: 'pages/users/_id.vue' }, { name: 'slug', path: '/:slug', component: 'pages/_slug/index.vue' }, { name: 'slug-comments', path: '/:slug/comments', component: 'pages/_slug/comments.vue' } ] } ## 处理404页面 Nuxt提供了一个专门捕捉 404 的情况,以助于我们更好的实现 404 之后的操作 > 在 pages 目录下创建一个名为 `.vue的vue文件,这个文件是专门用于捕捉 404 页面的,在此文件中可以更好的帮助我们捕捉 404 错误之后的操作 可以在此文件中添加 404 错误之后所需要执行的代码或者页面等 <a name="LlxpG"></a> # 中间件 <a name="XP6gv"></a> ## 创建 在项目根目录下,与pages目录同级,创建一个名为middleware的目录,此目录下的文件就是中间件 <a name="p346I"></a> ## 使用 <a name="FglJK"></a> ### 方法1 在nuxt.config.js` 文件中直接使用: javascript module.export = { router: { middleware: 'auto' // auto为中间件名称 } } ### 方法2 在组件中使用: ```vue ``` ## 执行顺序 1. 执行 `nuxt.config.js` 1. 匹配布局 1. 匹配页面 > 中间件可以异步执行,只需要返回一个 `Promise`或使用第 2 个 `callback` 作为第一个参数: ```javascript import axios from 'axios' export default function ({ route }) { return axios.post('http://my-stats-api.com', { url: route.fullPath }) } ``` # Loading 加载 **该属性用于页面跳转和加载页面时使用** ## 使用方法 ```javascript // 在 nuxt.config.js 文件中输入以下代码 module.exports = { loading: true } ``` > 将 true 改为 false,表示禁用加载进度条 ```javascript // 在所需要注册的组件内部输入以下代码 export default { mounted() { this.$nextTick(() => { this.$nuxt.$loading.start() setTimeout(() => this.$nuxt.$loading.finish(), 500) }) } } ``` > 若在 mounted 方法中调用,需使用 this.$nextTick 来调用,Loading 无法立即使用 ## 个性化加载进度条 | **键** | **类型** | **默认值** | **描述** | | --- | --- | --- | --- | | `color` | **String** | `'black'` | 进度条颜色 | | `failedColor` | **String** | `'red'` | 页面加载失败时的颜色(当`data`或`fetch`方法返回错误时) | | `height` | **String** | `'2px'` | 进度条的高度(在进度条元素的`style`属性上体现) | | `throttle` | **Number** | `200` | 在** ms **中,在显示进度条之前等待的时间,用于防止条形闪烁 | | `duration` | **Number** | `5000` | 进度条的最大显示时长,单位** ms**
**Nuxt.js **假设页面在该时长内加载完毕 | | `continuous` | **Boolean** | `false` | 当加载时间超过`duration`时,保持动画进度条 | | `css` | **Boolean** | `true` | 设置为** false **以删除默认进度条样式(并添加自己的样式) | | `rtl` | **Boolean** | `false` | 从右到左设置进度条的方向 | ## 自定义加载组件 > 新建一个加载组件代替 **Nuxt.js** 默认的,在 `loading` 配置项里指定组件的路径,**Nuxt.js** 会自动调用该组件 自定义组件需要实现以下接口方法: | **方法** | **是否必须** | **描述** | | --- | --- | --- | | `start()` | 是 | 路由更新(即浏览器地址变化)时调用,请在该方法内显示组件 | | `finish()` | 是 | 路由更新完毕(即`asyncData`方法调用完成且页面加载完)时调用,请在该方法内隐藏组件 | | `fail(error)` | 否 | 路由更新失败时调用(如`asyncData`方法返回异常) | | `increase(num)` | 否 | 页面加载过程中调用,`num`时小于 **100** 的整数 | 可以在`components`目录下创建自定义的加载组件,目录为 `components/loading.vue`: ```vue

然后更新`nuxt.config.js`,告诉 **Nuxt.js** 使用自定义加载组件:
```javascript
module.exports = {
  loading: '~/components/loading.vue'
}

Transition 过渡

路由切换时的过渡效果

使用方法

export default {
  // 字符类型
  transition: '',
  // 对象类型
  transition: {},
  // 函数类型
  transition (to, from) {}
}

只需在某个需要自定义过渡特效的组件中使用即可

<template>
  <transition name="test"></transition>
</template>

<script>
  export default {
    transition: 'test'
  }
</script>
// transition 值类型是字符类型,相当于设置了 transition.name 属性
<template>
  <transition name="test" mode="out-in"></transition>
</template>

<script>
  export default {
    transition: {
      name: 'test',
      mode: 'out-in'
    }
  }
</script>

更多方法见官网:transition

export default {
  transition(to, from) {
    if (!from) {
      return 'slide-left'
    }
    return +to.query.page < +from.query.page ? 'slide-right' : 'slide-left'
  }
}
  • / to /posts => slide-left
  • /posts to /posts?page=3 => slide-left
  • /posts?page=3 to /posts?page=2 => slide-right

asyncData 异步数据

asyncData方法会在组件(限于页面组件)每次加载之前被调用,在服务端或路由更新之前被调用
此方法被调用的时候,第一个参数被设定为当前页面的上下文对象,Nuxt会将 asyncData返回的数据融合组件data方法返回的数据一并返回给当前的组件

由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象

Layouts 布局

nuxt

<template>
  <div>
    <h1>Welcome</h1>
    <NuxtLink to="/about">
      About page
    </NuxtLink>
  </div>
</template>

<script>
  export default {
    layout: 'dark' // 将 dark.vue 布局组件应用在 index.vue 中
  }
</script>
// dark.vue 为布局组件,名字可随意取,默认为 default.vue
<template>
  <div>
    <Nuxt /> // 此为 pages/index.vue 的容器
  </div>
</template>

nuxt-child

<template>
  <div>
    <h1>我是父级页面</h1>
    <nuxt-child :foobar="123" />
  </div>
</template>
<template>
  <div>
    <h1>{{ foobar }}</h1>
  </div>
</template>

<script>
export default {
  props: ['foobar']
}
</script>

child.vue若不用 props接收,则nuxt-child中的属性将渲染为自定义 css 属性

nuxt-link

<template>
  <div>
    <h1>Home page</h1>
    <nuxt-link to="/about">关于</nuxt-link>
  </div>
</template>

别名:<n-link><NuxtLink><NLink>

Configuration 配置

css

// 安装 sass 所需的 npm 包
npm install --save-dev node-sass sass-loader

// nuxt.config.js 配置 css 所需资源
module.exports = {
  css: [
    // 直接加载一个 Node.js 模块。(在这里它是一个 Sass 文件)
    'bulma',
    // 项目里要用的 CSS 文件
    '@/assets/css/main.css',
    // 项目里要使用的 SCSS 文件
    '@/assets/css/main.scss'
  ]
}

component

// nuxt.config.js
export default {
  components: true,
}

开启后直接在 pages 目录下的页面组件中使用即可(例:components/Foo.vue == <Foo/>)

router

// nuxt.config.js
module.exports = {
  router: {
    base: '/app/' // 此时应用的根 url 为 http://localhost:3000/app/
  }
}

routeNameSplitter

// nuxt.config.js
export default {
  router: {
    routeNameSplitter: '/'
  }
}
// pages/posts/_id.vue  ==>     posts-id    修改前
// pages/posts/_id.vue  ==>        posts/id    修改后

extendRoutes

// nuxt.config.js
export default {
  router: {
    extendRoutes(routes, resolve) {
      routes.push({
        name: 'custom',
        path: '*',
        component: resolve(__dirname, 'pages/404.vue')
      })
    }
  }
}

server

// nuxt.config.js
export default {
  server: {
    port: 8000, // default: 3000
    host: '0.0.0.0' // default: localhost,
  }
}
// nuxt.config.js
import path from 'path'
import fs from 'fs'

export default {
  server: {
    https: {
      key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
      cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
    }
  }
}
// nuxt.config.js
export default {
  server: {
    socket: '/tmp/nuxt.socket'
  }
}

Programmatically 编程方式

Usage

const { Nuxt } = require('nuxt')
const options = {}
const nuxt = new Nuxt(options)
nuxt.build().then(() => {
  // 这里可以用 nuxt.render(req, res) 或者 nuxt.renderRoute(route, context)
})

render

const { Nuxt, Builder } = require('nuxt')

const app = require('express')()
const isProd = process.env.NODE_ENV === 'production'
const port = process.env.PORT || 3000

// 用指定的配置对象实例化 Nuxt.js
const config = require('./nuxt.config.js')
config.dev = !isProd
const nuxt = new Nuxt(config)

// 用 Nuxt.js 渲染每个路由
app.use(nuxt.render)

// 在开发模式下启用编译构建和热加载
if (config.dev) {
  new Builder(nuxt).build().then(listen)
} else {
  listen()
}

function listen() {
  // 服务端监听
  app.listen(port, '0.0.0.0')
  console.log('Server listening on `localhost:' + port + '`.')
}

Internals 内部构件

Hooks

nuxt.hook('ready', async nuxt => {
  // 自定义代码
})
Plugin Arguments When
ready (nuxt) Nuxt 实例初始化 (ModuleContainer 和 Renderer 已经准备好).
error (error) 调用 hooks 时出现未处理的错误。
close (nuxt) Nuxt 实例优雅地关闭。
listen (server, {host, port}) Nuxt内部服务器开始监听。 (使用 nuxt start 或 nuxt dev).