vue ssr 指南 学习笔记.

前置知识

  • 大概知道 vue 框架工作的方式.
  • 大概知道有 vue router 这么个东西.

概念

vue 框架的基本操作是通过指定页面模板和行为, 来渲染一个空的 div, 从渲染的时机来看, 用 vue 框架写的网站属于客户端渲染.当需要服务端渲染 (如 SEO) 的时候, 我们就不能采用常规的手段, 在请求到来的时候, 直接返回一个空的 div 和一个或者多个 js 文件了, 需要在服务端先把这段 js 跑一遍, 生成 html>body>manyDivs 标签.

vue 官方提供了 vue-server-renderer, 这个 renderer 通过传递一个 vue 实例渲染出一段 html.

以下是最小化地实现 vue ssr 的一段代码.

1
2
3
4
const app = new Vue(options);
renderer.renderToString(app, (err, html) => {
outputToClient(html);
}

生命周期

vue 为开发者提供了很多声明周期钩子函数, 需要分清楚, 当使用 ssr 的时候, 哪些钩子函数会被执行, 而另外一方面, 哪些钩子函数会在客户端被执行.

服务端环境和客户端环境不一致.

服务端渲染的引擎是 node, 客户端则是浏览器, 所以需要注意, 在服务端运行的那部分代码, 是不能使用浏览器特有而 node 没有的 api 如 window, document 等.

工程化构建

上面展示的最小化的示例代码, 采用了在 node 程序中直接新建 vue 实例的做法, 并不适合用于工程中. 引用官方文档-介绍构建步骤的一段话和一张图:

所以基本看法是,对于客户端应用程序和服务器应用程序,我们都要使用 webpack 打包 - 服务器需要「服务器 bundle」然后用于服务器端渲染(SSR),而「客户端 bundle」会发送给浏览器,用于混合静态标记。

也就是说, 我们想要做到的程度是

编写一份代码, 打包之后用于服务端渲染, 将丰富的 html 内容发到客户端, 客户端展示这段 html 之后, 由 js 接管页面, 转为常规的客户端渲染模式.

常规的单页面应用采用路由来组织不同的模块, 因此服务端也需要一致的渲染规则, 通过路由找到对应的 Vue 组件, 然后配合路由参数, 获取对应的数据, 最后构建出 vue 实例, 并且返回给 renderer.

代码看起来会是这样子:

1
2
3
4
5
6
7
// 如 www.xxx.com/articleDetail/{articleId}
const matchedComponent = router.getMatchedComponets();
// 建议使用全局状态管理, 如 vuex
// asyncState 为组件同步页面状态的静态方法.
const state = await matchedComponent.asyncState(router.params);
globalState.set(key, state);
return app;

至此, 服务端的渲染思路大概就是如此. 而客户端代码, 我们不需要做其他的改动.


以上只是记个大概的思路, 但是其他繁琐的细节比如 webpack 的配置之类的, 还是要看文档来搞, 毕竟思路比细节重要, 不是么?