nuxt学习笔记

nuxt.js相关概述

nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用Vue开发多页应用,并在服务端完成渲染,可以直接用命令把我们制作的vue项目生成为静态html。

那服务器端渲染到底有什么好处呢?

主要的原因时SPA(单页应用)不利于搜索引擎的SEO操作,Nuxt.js适合作新闻、博客、电影、咨询这样的需要搜索引擎提供流量的项目。如果你要作移动端的项目,就没必要使用这个框架了。

什么是SSR?

在认识SSR之前,首先对CSR与SSR之间做个对比。
首先看一下传统的web开发,传统的web开发是,客户端向服务端发送请求,服务端查询数据库,拼接HTML字符串(模板),通过一系列的数据处理之后,把整理好的HTML返回给客户端,浏览器相当于打开了一个页面。这种比如我们经常听说过的jsp,PHP,aspx也就是传统的MVC的开发。
SPA应用,到了Vue、React,单页面应用优秀的用户体验,逐渐成为了主流,页面整体式javaScript渲染出来的,称之为客户端渲染CSR。SPA渲染过程。由客户端访问URL发送请求到服务端,返回HTML结构(但是SPA的返回的HTML结构是非常的小的,只有一个基本的结构,如第一段代码所示)。客户端接收到返回结果之后,在客户端开始渲染HTML,渲染时执行对应javaScript,最后渲染template,渲染完成之后,再次向服务端发送数据请求,注意这里时数据请求,服务端返回json格式数据。客户端接收数据,然后完成最终渲染。
SPA虽然给服务器减轻了压力,但是也是有缺点的:

首屏渲染时间比较长:必须等待JavaScript加载完毕,并且执行完毕,才能渲染出首屏。
SEO不友好:爬虫只能拿到一个div元素,认为页面是空的,不利于SEO。

为了解决如上两个问题,出现了SSR解决方案,后端渲染出首屏的DOM结构返回,前端拿到内容带上首屏,后续的页面操作,再用单页面路由和渲染,称之为服务端渲染(SSR)。
SSR渲染流程是这样的,客户端发送URL请求到服务端,服务端读取对应的url的模板信息,在服务端做出html和数据的渲染,渲染完成之后返回html结构,客户端这时拿到的之后首屏页面的html结构。所以用户在浏览首屏的时候速度会很快,因为客户端不需要再次发送ajax请求。并不是做了SSR我们的页面就不属于SPA应用了,它仍然是一个独立的spa应用。
SSR是处于CSR与SPA应用之间的一个折中的方案,在渲染首屏的时候在服务端做出了渲染,注意仅仅是首屏,其他页面还是需要在客户端渲染的,在服务端接收到请求之后并且渲染出首屏页面,会携带着剩余的路由信息预留给客户端去渲染其他路由的页面。
Nuxt.js是特点(优点):

  • 基于Vue

  • 自动代码分层

  • 服务端渲染

  • 强大的路由功能,支持异步数据

  • 静态文件服务

  • EcmaScript6和EcmaScript7的语法支持

  • 打包和压缩JavaScript和Css

  • HTML头部标签管理

  • 本地开发支持热加载

  • 集成ESLint

  • 支持各种样式预编译器SASS、LESS等等

  • 支持HTTP/2推送

    Nuxt环境搭建

nuxt.js安装

  • 使用init命令来初始化Nuxt.js项目

    vue init nuxt/starter

  • 这时候他会在github上下载模版,然后会询问你项目的名称叫什么,作者什么的,这些完全可以根据自己的爱好填写。

  • 使用npm install安装依赖包

  • 使用npm run dev 启动服务

  • 在浏览器输入 localhost:3000,可以看到结果

    Nuxt 渲染流程

通过上面的流程图可以看出,当一个客户端请求进入的时候,服务端有通过nuxtServerInit这个命令执行在Store的action中,在这里接收到客户端请求的时候,可以将一些客户端信息存储到Store中,也就是说可以把在服务端存储的一些客户端的一些登录信息存储到Store中。之后使用了中间件机制,中间件其实就是一个函数,会在每个路由执行之前去执行,在这里可以做很多事情,或者说可以理解为是路由器的拦截器的作用。然后再validate执行的时候对客户端携带的参数进行校验,在asyncData与fetch进入正式的渲染周期,asyncData向服务端获取数据,把请求到的数据合并到Vue中的data中,

Nuxt目录结构

└─my-nuxt-demo

├─.nuxt // Nuxt自动生成,临时的用于编辑的文件,build

├─assets // 用于组织未编译的静态资源如LESS、SASS或JavaScript,对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中

├─components // 用于自己编写的Vue组件,比如日历组件、分页组件

├─layouts // 布局目录,用于组织应用的布局组件,不可更改⭐

├─middleware // 用于存放中间件

├─node_modules

├─pages // 用于组织应用的路由及视图,Nuxt.js根据该目录结构自动生成对应的路由配置,文件名不可更改⭐

├─plugins // 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。

├─static // 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。文件夹名不可更改。⭐

└─store // 用于组织应用的Vuex 状态管理。文件夹名不可更改。⭐

├─.editorconfig // 开发工具格式配置

├─.eslintrc.js // ESLint的配置文件,用于检查代码格式

├─.gitignore // 配置git忽略文件

├─nuxt.config.js // 用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。文件名不可更改。⭐

├─package-lock.json // npm自动生成,用于帮助package的统一设置的,yarn也有相同的操作

├─package.json // npm 包管理配置文件

├─README.md

配置文件

const pkg = require('./package')
module.exports = {
  mode: 'universal',    //  当前渲染使用模式
  head: {       //  页面head配置信息
    title: pkg.name,        //  title
    meta: [         //  meat
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: pkg.description }
    ],
    link: [     //  favicon,若引用css不会进行打包处理
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  loading: { color: '#fff' },   //  页面进度条
  css: [    //  全局css(会进行webpack打包处理)
    'element-ui/lib/theme-chalk/index.css'  
  ],
  plugins: [        //  插件
    '@/plugins/element-ui'
  ],
  modules: [        //  模块
    '@nuxtjs/axios',
  ],
  axios: {},
  build: {      //  打包
    transpile: [/^element-ui/],
    extend(config, ctx) {       //  webpack自定义配置
    }
  }
}

Nuxt常用配置项

1.配置IP和端口

开发中经常会遇到端口被占用或者指定IP的情况。我们需要在根目录下的package.json里对config项进行配置。比如现在我们想把IP配置成127.0.0.1,端口设置1000。

/package.json

"config":{
    "nuxt":{
      "host":"127.0.0.1",
      "port":"1000"
    }
  },

2.配置全局CSS

在开发多页项目时,都会定义一个全局的CSS来初始化我们的页面渲染,比如把padding和margin设置成0,网上也有非常出名的开源css文件normailze.css。要定义这些配置,需要在nuxt.config.js里进行操作。
比如现在我们要把页面字体设置为红色,就可以在assets/css/common.css文件,然后把字体设置为红色。

/assets/css/common.css

html{
    color:red;
}

/nuxt.config.js

css:['~assets/css/normailze.css'],

3.配置webpack的loader

在nuxt.config.js里是可以对webpack的基本配置进行覆盖的,比如现在我们要配置一个url-loader来进行小图片的64位打包。就可以在nuxt.config.js的build选项里进行配置.关可参照此链接https://www.cnblogs.com/ssh-007/p/7867954.html

build: {
    loaders:[
      {
        test:/\.(png|jpe?g|gif|svg)$/,
        loader:"url-loader",
        query:{
          limit:10000,
          name:'img/[name].[hash].[ext]'
        }
      }
    ],
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }

4.全局修改seo的head信息

nuxt.config.js文件中,修改title为wfaceboss:

head: {
   title: 'wfaceboss',
   meta: [
     { charset: 'utf-8' },
     { name: 'viewport', content: 'width=device-width, initial-scale=1' },
     { hid: 'description', name: 'description', content: 'Nuxt.js project' }
   ],
   link: [
     { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
   ]
 },

Nuxt的路由配置和参数传递

1.基本路由

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

2.页面跳转

1.不要写成a标签,因为是重新获取一个新的页面,并不是SPA

2.<nuxt-link to="/users"></nuxt-link>

3.this.$router.push(‘/users’)

3.动态路由

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

  • 获取动态参数

    4.跳转路由传递参数并且取值

    路由经常需要传递参数,我们可以简单的使用params来进行传递参数,我们现在向新闻页面(news)传递个参数,然后在新闻页面进行简单的接收。

(1)使用nuxt传递参数

<template>
  <div>
    <ul>
      <li><nuxt-link :to="`informa/${item.newsCode}-${item.newsType}`"></li>
    </ul>
  </div>
</template>

(2)使用nuxt接收参数

async asyncData(context) {
    let newsCode = context.route.params.code.split('-')[0]
    let newsType = context.route.params.code.split('-')[1]
}

(3)使用this.$router.push的params传递参数

传递参数  -- this.$router.push({path: ' 路由 ', query: {key: value}})
参数取值  -- this.$route.query.key

注: 使用这种方式,传递参数会拼接在路由后面,出现在地址栏

(4)使用this.$router.push的params传递参数

传递参数  -- this.$router.push({name: ' 路由的name ', params: {key: value}})
参数取值  -- this.$route.params.key

注: 使用这种方式,参数不会拼接在路由后面,地址栏上看不到参数

注意: 由于动态路由也是传递params的,所以在 this.$router.push() 方法中 path不能和params一起使用,否则params将无效。需要用name来指定页面。

路由参数校验

Nuxt.js 可以让你在动态路由对应的页面组件中配置一个validate方法用于校验动态路由参数的有效性。该函数有一个布尔类型的返回值,如果返回true则表示校验通过,如果返回false则表示校验未通过。

export default {
  // nuxt中使用validate方法进行路由参数校验,这个方法必须返回一个布尔值,为true表示校验通过,为false表示校验失败。注意validate不能写到methods属性中。
  validate(obj) {
    // console.log(obj);
    // return true
    return /^\d+$/.test(obj.params.id)
  }
}

嵌套路由

1.添加一个Vue文件,作为父组件
2.添加一个与父组件同名的文件夹来存放子视图组件
3.在父文件中,添加组件,用于展示匹配到的子视图

未完待续。。。。