前言
首先來講一下服務(wù)端渲染竞滓,直白的說就是在服務(wù)端拿數(shù)據(jù)進行解析渲染坯沪,直接生成html片段返回給前端署隘。具體用法也有很多種比如:
- 傳統(tǒng)的服務(wù)端模板引擎渲染整個頁面
- 服務(wù)渲染生成htmll代碼塊, 前端 AJAX 獲取然后js動態(tài)添加
服務(wù)端渲染的優(yōu)劣
首先是seo問題谓媒,前端動態(tài)渲染的內(nèi)容是不能被抓取到的蚯斯,而使用服務(wù)端渲染就可以解決這個問題况鸣。還有就是首屏加載過慢這種問題牢贸,比如在SPA中,打開首頁需要初始加載很多資源镐捧,這時考慮在首屏使用服務(wù)端渲染潜索,也是一種折中的優(yōu)化方案臭增。但是使用SSR時,勢必會增加服務(wù)器的壓力帮辟,還有可能會需要前后端同構(gòu)速址,使用同樣的模板引擎,這似乎與前后端分離的觀點又是矛盾的由驹。廢話就說到這里芍锚,下面來看一下vue框架中的服務(wù)器渲染。
vue-server-renderer
vue-server-renderer就是vue中處理服務(wù)端加載的一個模塊了蔓榄,官方文檔:https://ssr.vuejs.org/en/并炮,暫時沒有中文版的,我也只是稍微看了一些甥郑,然后寫了一個簡單的demo逃魄。首先新建一個test.js文件,并用npm安裝依賴express澜搅、vue伍俘、vue-server-renderer。引入vue-server-renderer之后勉躺,然后新建一個temp.html作為渲染的基本模板癌瘾,用createRenderer方法新建一個render實例,這里我傳入temp.html作為renderer的template的參數(shù)饵溅,在后面渲染時就會以這個temp.html作為基礎(chǔ)模板妨退。
const renderer = require('vue-server-renderer').createRenderer({
template: require('fs').readFileSync('./temp.html', 'utf-8')
})
temp.html:
<!DOCTYPE html><br><html lang="en"><br><head><title>{{title}}</title></head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
接下來隨便定義一些渲染用的數(shù)據(jù),然后用express新建一個node服務(wù)器蜕企,再定義一個vue的實例咬荷。然后再調(diào)用renderer的renderToString方法來渲染生成html,渲染成功后返回給客戶端轻掩。
const Vue = require('vue')
const server = require('express')()
const context = {
title: 'hello'
}
const mocktitle = '我愛吃的水果'
const mockdata = ['香蕉', '蘋果', '橘子']
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url,
data: mockdata,
title: mocktitle
},
template: `<div>The visited URL is: {{ url }}
<h3>{{title}}</h3>
<p v-for='item in data'>{{item}}</p>
</div>`
})
renderer.renderToString(app, context, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
server.listen(8080)
注意這里渲染的數(shù)據(jù)有兩種幸乒,mockdata是作為vue實例的data來渲染在實例模板中的,而context是作為基礎(chǔ)模板的data來渲染temp.html的唇牧∈疟洌可以看到在服務(wù)端用vue進行渲染的規(guī)則和前端渲染時一樣,v-for奋构、v-if等都可以正常使用。最后命令行輸入node test.js拱层,然后在瀏覽器打開http://localhost:8080 查看結(jié)果如下:
可以看到服務(wù)端直接返回了一個渲染完成的Doc弥臼,示例demo到此結(jié)束。
結(jié)語
服務(wù)端渲染還是客戶端渲染的問題根灯,個人覺得還是要針對具體業(yè)務(wù)場景然后再做選擇径缅。