nuxt.js的ssr渲染
1、为什么要用到nuxt?有什么优势?
1.1 为什么要用到nuxt?
- 首先要了解nuxt是什么?具体有什么作用?
Nuxt.js:Vue.js的通用框架,集成了vue2、vue-route、vuex、vue ssr、vue-meta等组件/框架,其是用webpack、和vue-loader、babel-loader来处理代码的自动化构建工作(打包、代码分层、压缩等
作用:
- 用做于SSR(服务器渲染)。简单理解,Vue.js原来是开发SPA(单页应用)的,但是随着技术的普及。很多人想用Vue开发多页应用,并在服务端完成渲染。这时候就出现了Nuxt.js这个框架,它简化了SSR的开发难度。还可以直接用命令把我们制作的vue项目生成为静态html。
- ssr又是什么?有什么用?
ssr: 服务器渲染,在服务器端将对Vue页面进行渲染生成html文件,将html页面传递给浏览器
使用ssr的背景:
- 纯vue写的项目,由Vue-cli集成的webpack打包还有代码压缩处理后生成一串js的静态文件,蜘蛛无法对纯js的网页进行爬取收录,不利于网站的排名,而nuxt刚好是vue团队打造的基于vue的ssr的框架。
作用:
- 在SEO上:SPA的HTML只有一个无实际内容的HTML和一个app.js,而SSR生成的HTML是有内容的,这让搜索引擎能够索引到页面内容
- 大大加快了首屏加载时间:传统的SPA应用是将bundle.js从服务器获取,然后在客户端解析并挂载到dom。而SSR直接将HTML字符串传递给浏览器。
- 什么时候用到nuxt.js
当要对vue项目做SEO优化,提高百度、谷歌等搜索引擎对网站的收录,提高蜘蛛的爬取
1.2 有什么优势?
- 优势:
1.基于 Vue.js
2.自动代码分层
3.服务端渲染
4.强大的路由功能,支持异步数据
5.静态文件服务
6.ES6/ES7 语法支持
7.打包和压缩 JS 和 CSS
8.HTML头部标签管理
9.本地开发支持热加载
10.集成ESLint
11.支持各种样式预处理器: SASS、LESS、 Stylus等
12.nuxt自己集成了vuex,所以不需要安装,在/store目录下新建index.js即可使用
2、nuxt.js在server和client端渲染的相关问题
2.1. 首先要了解nuxt.js的生命周期
以下是 nuxt.js 的生命周期流程图:
- 红框内的是Nuxt 的生命周期(运行在服务端),
- 黄框内同时运行在服务端&&客户端上,
- 绿框内则运行在客户端
- 关于不能调用window的问题
因为 红框、黄框内的周期在服务端运行,所以都不存在Window对象,所以不能直接使用window
<script>
export default {
asyncData() {
console.log(window) // 服务端报错
},
fetch() {
console.log(window) // 服务端报错
},
created () {
console.log(window) // undefined
},
mounted () {
console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
}
}
</script>
- 整个页面流程:当页面第一次加载或者重新reload页面时,会从上向下一次执行,但是之后的路由跳转都是在client端中执行,和server端就没什么关系了,包括页面中的asyncData,其实我一开始以为asyncData是一直在server端运行,其实并不是,除了第一次加载,其他的通过路由跳转的asyncData都是在client端运行
- incoming request
- 这个阶段是服务器收到请求,开始走流程
- nuxtServerInit
- 服务器初始化
- 只能够在store/index.js中使用
- 用于在渲染页面之前存储数据到vuex中
- 接受两个参数:vuex上下文,和nuxt上下文
actions: { nuxtServerInit ({ commit }, { req }) { if (req.session.user) { commit('user', req.session.user) } } } //异步 nuxtServerInit 操作必须返回一个 Promise 或利用 async/await 来允许 nuxt 服务器等待它们。 actions: { async nuxtServerInit({ dispatch }) { await dispatch('core/load') } }
- middleware
- 这个阶段会执行一些预定义的中间件,自己定义的中间件也会在这个阶段执行
- 第一次进入页面或者刷新页面是在server端运行,之后的路由跳转是在client端运行
- 如果你写的是一个插件,那么如果你设置了该插件的属性为sse:false,表示只会在客户端运行该插件,如果你设置为了true,则表示既会在客户端运行,也会在服务器端运行
- 如在nuxt中使用axios,有两种方式:
1.写两个req 的api作为两个插件: 一个在服务器请求名字为server-api.js,(服务端请求+asyncData中的请求)ssr设为true,一个在客户端请求 名为client-api.js,ssr设为false
2. 只写一个re的qpi作为一个插件:将其ssr设为true即可 - validate :
- 可以让你在动态路由对应的页面组件中配置一个校验方法用于校验动态路由参数的有效性
- validate每次在导航到新路线之前都会调用
validate({ params, query, store }) { return true // if the params are valid return false // will stop Nuxt to render the route and display the error page }
- asyncData()和fecth()
- asyncData(): 你能够在渲染组件之前异步获取数据。好比你在vue组件中用created获取数据一样,不同的是asyncData是在服务端执行的
注意:asyncData只是在首屏的时候调用一次(即页面渲染之前,所以事件触发不了它) - fectch(): 它会在组件每次加载前被调用(在服务端或切换至目标路由之前),同时为了让获取过程可以异步,你需要返回一个 Promise,Nuxt.js 会等这个 promise 完成后再渲染组件
- 两者使用可看具体用法:asyncData()和fecth()
- asyncData(): 你能够在渲染组件之前异步获取数据。好比你在vue组件中用created获取数据一样,不同的是asyncData是在服务端执行的
- render
- 这个阶段开始准备客户端渲染,如果过程中有通过nuxt-link跳转,会退回至middleware阶段重新执行
- beforeCreat和created阶段
- 这个和vue中的钩子函数功能基本类似,有一个小的差别:
- vue的这两个钩子只在客户端执行;
- nuxt的这两个钩子在客户端和服务端都会执行一遍
- 其他阶段: 之后的阶段都是在客户端中执行,比如beforeMount和mounted阶段等等
参考文章: