摘要:當(dāng)然你可以采用頁(yè)面模板的形式,將兩者相分離這里將是應(yīng)用程序標(biāo)記注入的地方中包含了模板當(dāng)然這只是最簡(jiǎn)單的一個(gè)例子,瀏覽器收到的僅僅是對(duì)應(yīng)實(shí)例的代碼,并沒(méi)有將其激活,因此是不可交互的。
前言
首先歡迎大家關(guān)注我的Github博客,也算是對(duì)我的一點(diǎn)鼓勵(lì),畢竟寫(xiě)東西沒(méi)法獲得變現(xiàn),能堅(jiān)持下去也是靠的是自己的熱情和大家的鼓勵(lì)。
Vue同構(gòu)也就是我們常說(shuō)的服務(wù)器渲染(Server Side Render),服務(wù)器渲染放在今天已經(jīng)算不上是一個(gè)新鮮的東西了,從React到Vue都有各自的服務(wù)器渲染方案,很多小伙伴可能都有所接觸,首先我們要了解一下為什么需要服務(wù)器渲染呢?Vue和React這類(lèi)框架有一個(gè)特點(diǎn),都屬于瀏覽器渲染,比如一個(gè)最簡(jiǎn)單的例子:
{{ message }}
var app = new Vue({ el: "#app", data: { message: "Hello Vue!" } })
我們可以看到,我們收到服務(wù)器的模板中其實(shí)并沒(méi)有我們所期待界面對(duì)應(yīng)的html結(jié)構(gòu),而僅有一個(gè)用于掛載應(yīng)用的根元素,在客戶端瀏覽器執(zhí)行加載的JavaScript代碼時(shí),才會(huì)創(chuàng)建對(duì)應(yīng)的DOM結(jié)構(gòu)。然而瀏覽器渲染其實(shí)存在兩個(gè)明顯的缺點(diǎn):
對(duì)搜索引擎優(yōu)化(SEO:Search Engine Optimization)不友好,各個(gè)搜索引擎實(shí)際上都是對(duì)網(wǎng)頁(yè)的html結(jié)構(gòu)和同步Javascript代碼進(jìn)行索引,因而客戶端渲染可能會(huì)造成你的網(wǎng)頁(yè)無(wú)法被搜索引擎正確索引。
TTC(內(nèi)容到達(dá)時(shí)間:Time-To-Conten)過(guò)長(zhǎng),試想如果設(shè)備的網(wǎng)絡(luò)較差或者設(shè)備的代碼執(zhí)行速度較慢,用戶需要等待較長(zhǎng)的時(shí)間才能看到頁(yè)面的內(nèi)容,等待期間看到的都是網(wǎng)頁(yè)的白屏或者其他的加載狀態(tài),這絕對(duì)是糟糕的用戶體驗(yàn)。
幸運(yùn)的是,Node的到來(lái)為這一切帶來(lái)了曙光,JavaScript不僅僅可以在瀏覽器中執(zhí)行,而且也可能在后端環(huán)境中執(zhí)行。因此我們可以將用戶的界面在服務(wù)器中渲染成HTML 字符串,然后再傳給瀏覽器,這樣用戶獲得的就是可預(yù)覽的界面,最后將靜態(tài)標(biāo)記"混合"為客戶端上完全交互的應(yīng)用程序,整個(gè)渲染的過(guò)程就結(jié)束了。
最簡(jiǎn)單的例子Vue服務(wù)器渲染使用官方提供的庫(kù)vue-server-renderer,由于Express比較直觀,我們采用Express作為后端服務(wù)器,我們首先給出一個(gè)最簡(jiǎn)單的例子:
// server.js const Vue = require("vue") const server = require("express")() // 創(chuàng)建一個(gè) renderer const renderer = require("vue-server-renderer").createRenderer() server.get("*", (req, res) => { // 創(chuàng)建一個(gè) Vue 實(shí)例 const app = new Vue({ data: { url: req.url }, template: `訪問(wèn)的 URL 是: {{ url }}` }) renderer.renderToString(app, (err, html) => { if (err) { res.status(500).end("Internal Server Error") return } // html就是Vue實(shí)例app渲染的html res.end(`Hello ${html} `) }) }) server.listen(8080)
然后啟動(dòng)node server.js,并且瀏覽器中訪問(wèn)比如http://localhost:8080/app,瀏覽器界面中則會(huì)顯示出:
訪問(wèn)的 URL 是:/app
這時(shí)候觀察該請(qǐng)求的返回值是:
我們發(fā)現(xiàn)返回的html中已經(jīng)渲染好DOM元素。因此我們無(wú)需等待立即可以看見(jiàn)頁(yè)面的內(nèi)容。而上面的代碼邏輯也非常簡(jiǎn)單,http服務(wù)器接收到get請(qǐng)求的時(shí)候,都會(huì)創(chuàng)建一個(gè)Vue實(shí)例,vue-server-renderer中的createRenderer用來(lái)創(chuàng)建一個(gè)Renderer實(shí)例,Renderer中的renderToString用來(lái)將Vue實(shí)例轉(zhuǎn)化對(duì)應(yīng)的HTML字符串,需要注意的是,我們需要將創(chuàng)建好的字符串包裹在html一并返回。當(dāng)然你可以采用頁(yè)面模板的形式,將兩者相分離:
Hello