这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
(本文基于 Vue 2.x 讨论,Vue 3.x 待有输入时再输出)
SSR
SSR,Server Side Render,服务端渲染,# 官方指南 了解一下~
Vue.js 也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
简言之,SSR,浏览器会得到已在服务器端渲染的 HTML 字符串。
Q:那服务端渲染与常用的客户端渲染有什么不一样?
A:进行简单对比
类型 | 简要步骤 | 主要特点 |
---|---|---|
客户端渲染 | 1、访问网站 2、服务端返回包含引入资源语句的 HTML 文件 3、向服务端请求资源 4、资源加载完毕后渲染页面 | 直接返回 HTML 文件 |
服务端渲染 | 1、访问网站 2、服务器查看需要哪些资源文件 3、填充内容到 HTML 文件(有 Ajax 请求会进行数据预取并填充) 4、客户端接受 HTML 页面马上开始渲染页面(同时加载资源) | 渲染完页面再返回 HTML 文件 |
可见,SSR有两大优点:
-
首屏渲染快,因为从服务端返回 HTML 字符串,减少加载JS资源的时间,是性能优化的一种手段;
-
利于SEO,HTML 文件在服务端填充,方便网络爬虫
黑盒子: Nuxt.js
本文选择 Nuxt.js 为入口去了解 SSR。那为什么呢?
如果你倾向于使用提供了平滑开箱即用体验的更高层次解决方案,你应该去尝试使用 Nuxt.js。 Nuxt.js 通过对客户端/服务端基础架构的抽象组织,且预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。( # Nuxt.js )
搭建项目
使用 Nuxt.js 提供的脚手架工具 create-nuxt-app
创建项目,具体步骤见 # 传送门
package.json 如下,具体介绍:# 命令列表
{
"scripts": {
"dev": "nuxt", // 启动一个热加载的 Web 服务器(开发模式)
"build": "nuxt build", // 利用 webpack 编译应用,压缩 JS 和 CSS 资源(发布用)
"start": "nuxt start", // 以生产模式启动一个 Web 服务器 (需要先执行`nuxt build`)
"generate": "nuxt generate" // 编译应用,并依据路由配置生成对应的 HTML 文件 (用于静态站点的部署)
},
}
开发模式
执行npm run dev,启动项目
如上图所示,发现运行两个端:√ Client & √ Server
启动时 nuxt,它将启动具有热更新加载的开发服务器,并且 Vue 服务器端渲染配置为自动为服务器呈现应用程序
即开发模式时,Nuxt.js 会运行服务端和客户端
组件如何支持SSR
即如何开发支持服务端渲染的程序,那组件开发时,要注意什么问题呢?
-
重要声明:服务端无 window、document
-
Nuxt 2.x(基于Vue 2.x)程序中,客户端和服务端均被调用的有:
- 1、beforeCreate(# nuxt-plugins)
- 2、created
- 3、watch with immediate(immediate 为 true)
- 4、computed with view(展示在视图)
- 5、data 函数定义的数据
- 7、引用的 mixins、子组件、inject对应的1-5点要注意
(框内
Nuxt SSR
代表在服务端被调用,框外指客户端)结合上一点,开发组件时,需注意上述均不能直接使用 window、document ,否则报错,应添加判断,避免在服务端执行,在客户端渲染时才执行
import Vue from 'vue' const isServer = Vue.prototype.$isServer; if (isServer) return;
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行
-
自定义指令
Vue 2.x 的自定义指令钩子函数有:
- bind
- inserted
- update
- componentUpdated
- unbind
vue 2.6.14,nuxt 2.15.8,自定义指令钩子函数未在服务端被调用,可以使用
-
异步数据
组件开发中:
-
若是普通数据(非异步数据),初始化到 data 函数 中即可
-
若是业务组件(需先请求接口),即动态获取异步数据,就需运用 Nuxt.js 的 asyncData 方法发送请求
export default { async asyncData () { const res = await axios({...opts}) return res.data } }
注意事项:
-
可在服务端或路由更新之前被调用
-
在组件 初始化 前被调用的,无 this
-
链接传送门
Last but not least
如有不妥,请多指教~