摘要:当然你可以采用页面模板的形式,将两者相分离这里将是应用程序标记注入的地方中包含了模板当然这只是最简单的一个例子,浏览器收到的仅仅是对应实例的代码,并没有将其激活,因此是不可交互的。
前言
首先欢迎大家关注我的Github博客,也算是对我的一点鼓励,毕竟写东西没法获得变现,能坚持下去也是靠的是自己的热情和大家的鼓励。
Vue同构也就是我们常说的服务器渲染(Server Side Render),服务器渲染放在今天已经算不上是一个新鲜的东西了,从React到Vue都有各自的服务器渲染方案,很多小伙伴可能都有所接触,首先我们要了解一下为什么需要服务器渲染呢?Vue和React这类框架有一个特点,都属于浏览器渲染,比如一个最简单的例子:
{{ message }}
var app = new Vue({ el: "#app", data: { message: "Hello Vue!" } })
我们可以看到,我们收到服务器的模板中其实并没有我们所期待界面对应的html结构,而仅有一个用于挂载应用的根元素,在客户端浏览器执行加载的JavaScript代码时,才会创建对应的DOM结构。然而浏览器渲染其实存在两个明显的缺点:
对搜索引擎优化(SEO:Search Engine Optimization)不友好,各个搜索引擎实际上都是对网页的html结构和同步Javascript代码进行索引,因而客户端渲染可能会造成你的网页无法被搜索引擎正确索引。
TTC(内容到达时间:Time-To-Conten)过长,试想如果设备的网络较差或者设备的代码执行速度较慢,用户需要等待较长的时间才能看到页面的内容,等待期间看到的都是网页的白屏或者其他的加载状态,这绝对是糟糕的用户体验。
幸运的是,Node的到来为这一切带来了曙光,JavaScript不仅仅可以在浏览器中执行,而且也可能在后端环境中执行。因此我们可以将用户的界面在服务器中渲染成HTML 字符串,然后再传给浏览器,这样用户获得的就是可预览的界面,最后将静态标记"混合"为客户端上完全交互的应用程序,整个渲染的过程就结束了。
最简单的例子Vue服务器渲染使用官方提供的库vue-server-renderer,由于Express比较直观,我们采用Express作为后端服务器,我们首先给出一个最简单的例子:
// server.js const Vue = require("vue") const server = require("express")() // 创建一个 renderer const renderer = require("vue-server-renderer").createRenderer() server.get("*", (req, res) => { // 创建一个 Vue 实例 const app = new Vue({ data: { url: req.url }, template: `访问的 URL 是: {{ url }}` }) renderer.renderToString(app, (err, html) => { if (err) { res.status(500).end("Internal Server Error") return } // html就是Vue实例app渲染的html res.end(`Hello ${html} `) }) }) server.listen(8080)
然后启动node server.js,并且浏览器中访问比如http://localhost:8080/app,浏览器界面中则会显示出:
访问的 URL 是:/app
这时候观察该请求的返回值是:
我们发现返回的html中已经渲染好DOM元素。因此我们无需等待立即可以看见页面的内容。而上面的代码逻辑也非常简单,http服务器接收到get请求的时候,都会创建一个Vue实例,vue-server-renderer中的createRenderer用来创建一个Renderer实例,Renderer中的renderToString用来将Vue实例转化对应的HTML字符串,需要注意的是,我们需要将创建好的字符串包裹在html一并返回。当然你可以采用页面模板的形式,将两者相分离:
Hello