NuxtJS基础

390 阅读3分钟

Nuxt.js 介绍

是什么

Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架,它可以帮我们轻松的实现同构应用。 通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI渲染。

我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。

Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。

除此之外,还提供了一种命令叫: nuxt generate ,为基于 Vue.js 的应用提供生成对应的静态站点的功能。

我们相信这个命令所提供的功能,是向开发集成各种微服务(Microservices)的 Web 应用迈开的新一步。

作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据 加载、中间件支持、布局支持等非常实用的功能。

特性

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

如何运作的

Nuxt.js 集成了以下组件/框架,用于开发完整而强大的 Web 应用:

  • Vue.js
  • Vue Router
  • Vuex
  • Vue Server Renderer

压缩并 gzip 后,总代码大小为:57kb (如果使用了 Vuex 特性的话为 60kb)。

另外,Nuxt.js 使用 Webpack 和 vue-loader 、 babel-loader 来处理代码的自动化构建工作(如打包、 代码分层、压缩等等)。

如何使用

  • 初始项目
  • 已有的 Node.js 服务端项目
    • 直接把 Nuxt 当作一个中间件集成到Node Web Server中
  • 现有的Vue.js项目
    • 非常熟悉 Nuxt之后
    • 至少百分之十的改动

创建项目

Nuxt 提供了两种方式用来创建项目:

  • 使用 create-nuxt-app 脚手架工具
  • 手动创建 通过手动创建的方式来学习 Nuxt
  1. 准备
# 创建示例项目
mkdir nuxt-app-demo
# 进入示例项目目录中 
cd nuxt-app-demo
# 初始化 package.json 文件 
npm init -y
# 安装 nuxt
npm innstall nuxt

在 package.json 文件的 scripts 中新增:

"scripts": {
  "dev": "nuxt"
},

上面的配置使得我们可以通过运行 npm run dev 来运行 nuxt 。

  1. 创建页面并启动项目 创建目录:
mkdir pages

创建我们的第一个页面 pages/index.vue :

<template>
  <h1>Hello world!</h1>
</template>

然后启动项目:

npm run dev

由于是同构应用,所以需要构建两个端(客户端,服务端)

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

注意:Nuxt.js 会监听 pages 目录中的文件更改,因此在添加新页面时无需重新启动应用程序。

Nuxt 路由

Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。

基础路由

假设 pages 的目录结构如下:

pages/
--| user/
-----| index.vue 
-----| one.vue 
--| index.vue

那么,Nuxt.js 自动生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    }, 
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    }, 
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    } 
  ]
}

路由导航

  • a 标签
    • 它会刷新整个页面
    • 刷新后走服务端渲染
  • nuxt-link 组件(与vue的router-link相似)
<nuxt-link to="/">首页<nuxt-link/>
  • 编程式导航
this.$router.push('/)

动态路由

在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。

以下目录结构:

pages/
--| _slug/
-----| comments.vue 
-----| index.vue 
--| users/
-----| _id.vue
--| index.vue

Nuxt.js 生成对应的路由配置表为:

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'
    } 
  ]
}

嵌套路由

你可以通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由。

创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。

Warning: 别忘了在父组件( .vue 文件) 内增加 用于显示子视图内容。

假设文件结构如:

pages/
--| users/ 
-----| _id.vue 
-----| index.vue 
--| users.vue

Nuxt.js 自动生成的路由配置如下:

router: {
  routes: [
    {
      path: '/users',
      component: 'pages/users.vue', 
      children: [
        {
          path: '',
          component: 'pages/users/index.vue', 
          name: 'users'
        }, 
        {
          path: ':id',
          component: 'pages/users/_id.vue', 
          name: 'users-id'
    	} 
      ]
    } 
  ]
}

路由配置

module.exports = {
  router: {
    base: '/app'
  }
}

重启应用,应用运行在 http://localhost:3000/app/ 上运行。

自定义路由配置

扩展路由

nuxt.config.js - Nuxt 配置文件

export default {
  router: {
  // routes 路由配置表
  // resolve 解析路由组件路径
    extendRoutes(routes, resolve) {
      routes.push({
        name: 'custom',
        path: '*',
        component: resolve(__dirname, 'pages/404.vue')
      })
    }
  }
}

Nuxt 视图

模板

可以定制化 Nuxt.js 默认的应用模板,只需要在 src 文件夹下(默认是应用根目录)创建一个 app.html 的文件 默认模板为:

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>

布局

Nuxt.js 允许你扩展默认的布局,或在 layout 目录下创建自定义的布局。

  1. 默认布局 可通过添加 layouts/default.vue 文件来扩展应用的默认布局。

提示: 别忘了在布局文件中添加<nuxt />组件用于显示页面的主体内容。 默认布局的源码如下:

<template>
  <nuxt />
</template>
  1. 自定义布局

异步数据

asyncData

Nuxt.js 扩展了 Vue.js,增加了一个叫* asyncData *的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。

调用时机:asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。

  1. 服务端渲染该页面期间调用
  2. 客户端路由导航到该页面之前被调用

基本用法: asyncData返回的数据 融合 组件data方法返回数据 一并给组件

async asyncData () {
    // 如果验证asyncData是在服务端执行的?可以通过log输出在了服务端控制台,得出这个方法是在服务端执行的。Nuxtjs为了方便调试,把服务端控制台输出数据也打印在了客户端控制台,但是为了区分,在客户端控制台用“Nuxt SSR”包裹起来了
    console.log('asyncData')
    const res = await axios({
      method: 'GET',
      url: 'http://localhost:3000/data.json'// 这里的请求地址要写完整,因为在服务端渲染期间,也要来请求数据,不写完整的话服务端渲染就会走到80端口,如果只是客户端渲染,就会以3000端口为基准来请求根目录下的data.json,服务端渲染就默认走到80了
    })
    // 返回的数据会与data中的数据混合
    return res.data
  },

注意事项:

  1. 当你想要动态页面内容有利于 SEO 或者是提升首屏渲染速度的时候,就在 asyncData 中发请求拿数据, 如果是非异步数据或者普通数据,则正常的初始化到 data 中即可
  2. 只能在页面文件中使用,如果子组件中需要数据,可以通过props方式传递数据
  3. 没有this,因为它是在组件初始化之前被调用的

上下文对象 context

可通过 context 来了解该对象的所有属性和方法。

async asyncData (context) {
    // asyncData的参数为上下文对象,我们无法在这个方法里使用this,所以无法通过this.$router.params.id拿到路由参数,但是可以通过context.params.id获取参数
    console.log(context) 
    const { data: {posts} } = await axios({
      method: 'GET',
      url: 'http://localhost:3000/data.json'
    })
    const id = parseInt(context.params.id, 10)
    return {
      post: posts.find(item => item.id === id),
    }
  }