nuxt简介

官方教程

  • 为解决spa应用的seo问题和网站加载速度问题,可以使用服务端渲染(ssr)
  • nuxt是基于vue的服务端渲染框架
  • 其缺点是:
    • 服务端渲染增加了服务端性能消耗
    • ie兼容性
    • 退化处理成本

nuxt生命周期

1.png

1. 请求首先触发nuxtServerInit函数

  • 当请求打入时,最先调用的即是 nuxtServerInit 方法,可以通过这个方法预先将服务器的数据保存,如已登录的用户信息等。
  • 另外,这个方法中也可以执行异步操作,并等待数据解析后返回

2. middleware层

经过第一步后,请求会进入 Middleware 层,在该层中有三步操作:

  1. 读取 nuxt.config.js 中全局 middleware 字段的配置,并调用相应的中间件方法
  2. 匹配并加载与请求相对应的 layout
  3. 调用 layout 和 page 的中间件方法

3. 调用 validate 方法

  • 在这一步可以对请求参数进行校验
  • 或是对第一步中服务器下发的数据进行校验,如果校验失败,将抛出 404 页面。

4. 调用 fetch 及 asyncData 方法

这两个方法都会在组件加载之前被调用,它们的职责各有不同

  • asyncData 用来异步的进行组件数据的初始化工作
  • fetch 方法偏重于异步获取数据后修改 Vuex 中的状态

5. 渲染

在 .nuxt 目录下,你可以找到 server.js 文件,这个文件封装了 Nuxt.js 在服务端渲染的逻辑。

我遇到的nuxt坑

1. 自动构建选择了spa模式

问题复现

当使用yarn create nuxt-app mynuxt命令开始交互式生成nuxt开箱即用项目时,有这样一步交互:
2.png
由于我的vue应用是单页面应用,因此此处选成了SPA,最终项目由前端spa迁移为nuxt时,发现页面并没有被服务端渲染,首页源码如下,并未渲染出html结构:
5.png
nuxt服务端渲染正确的源码应该有明确html结构:
123.png

问题原因

nuxt有两种模式,在其全局配置文件nuxt.config.js中可以这样配置:
3.png
默认为:

mode:'universal'

交互生成项目阶段选为spa则为:

mode:'spa'

问题分析

关于这两种模式,官网说明很简单,即

‘spa’: 没有服务器端渲染(只有客户端路由导航等)
‘universal’: 同构应用程序(服务器端呈现+客户端路由导航等)

spa

使用spa模式意味着:原vue spa应用的router由nuxt的page目录负责实现,但其他部分仍然遵循客户端spa的写法

  • 为了使得渲染前得到接口数据,可以在asyncData方法中写接口,接口数据返回后融合进vue实例的data中,可以在vue中使用
  • 缺点在于这依然是spa模式,由于服务端没渲染出HTML结构,seo并没有解决,失去了使用nuxt的意义

universal

使用默认模式,即universal模式才会生成真正的服务端渲染结构

2. asyncData中的接口刷新本地启服务会报错

理想情况

服务端渲染生效后,客户端浏览器devtools中应该看不到显式的http请求,请求已经再服务端完成了,返回的直接是一个静态页的地址

调试情况

调试时,由于在本地启动nuxt,因此可能出现服务端应该渲染的接口没有请求的情况,造成如下错误:
1.png
因为asyncData中的内容需要在服务端执行,客户端不能执行

浅析

直接yarn dev,本地环境模拟服务端可能会失败,这个原因暂时没找到,可能需要进一步了解webpack和node机制才行

解决

这时,应该yarn build再yarn start来查看
注意: 这个问题可能是开发生产环境配置问题,等待后续nuxt升级与优化

3. elementui不能cdn化

  • 由于elementui导致最终生成的包过大,所以想到将elementui做成cdn来优化页面加载时间
  • 直接将elementui做成cdn是不可行的,原因如下:
    1. elementui做成cdn是客户端加载,elementui必须要在服务端加载并转义为普通html后再渲染吐给前端
    2. elementui依赖vue,nuxt本身集成vue但没有显式暴露vue实例,单独cdn的elementui是无效的

注意: 这个问题有几次issue但并未解决