安装
npm install vue vue-server-renderer --save
1. 渲染一个 Vue 实例
新建文件vue-demo.js
// 第 1 步:创建一个 Vue 实例
const Vue = require('vue')
const app = new Vue({
template: `<div>Hello World</div>`
})
// 第 2 步:创建一个 renderer
const renderer = require('vue-server-renderer').createRenderer()
// 第 3 步:将 Vue 实例渲染为 HTML
renderer.renderToString(app, (err, html) => {
if (err) throw err
console.log(html)
// => <div data-server-rendered="true">Hello World</div>
})
// 在 2.5.0+,如果没有传入回调函数,则会返回 Promise:
renderer.renderToString(app).then(html => {
console.log(html)
}).catch(err => {
console.error(err)
})
需要在node环境下运行
node vue-demo.js
2. 与服务器Express集成
npm install express --save
新建文件express-server.js
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: `<div>visit URL is {{ url }}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello inner HTML</title></head>
<body>${html}</body>
</html>
`)
})
})
server.listen(8080)
node express-server.js
3. 从文件中读取模版,取代字符串模版
当你在渲染 Vue 应用程序时,renderer 只从应用程序生成 HTML 标记 (markup)。在这个示例中,我们必须用一个额外的 HTML 页面包裹容器,来包裹生成的 HTML 标记。
为了简化这些,你可以直接在创建 renderer 时提供一个页面模板。多数时候,我们会将页面模板放在特有的文件中
index.template.html
<!DOCTYPE html>
<html lang="en">
<head><title>Hello outer HTML</title></head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
注意 注释 — 这里将是应用程序 HTML 标记注入的地方。
vue-tpl.html
<div>vue-tpl.html => visit URL is {{ url }} </div>
express-server2.js
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: require('fs').readFileSync('./vue-tpl.html', 'utf-8')
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
server.listen(8080)
4. 模板插值
index.template3.html
<!DOCTYPE html>
<html lang="en">
<head><title>{{ title }}</title></head>
<body>
<div>1</div>
<!--vue-ssr-outlet-->
<div>2</div>
</body>
</html>
express-server3.js
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer({
template: require('fs').readFileSync('./index.template3.html', 'utf-8')
})
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: `<div>visit URL is {{ url }} </div>`
})
const context = {
title: 'variable title',
}
renderer.renderToString(app, context, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
server.listen(8080)
也可以与 Vue 应用程序实例共享 context 对象,允许模板插值中的组件动态地注册数据。
此外,模板支持一些高级特性,例如:
- 在使用 *.vue 组件时,自动注入「关键的 CSS(critical CSS)」;
- 在使用 clientManifest 时,自动注入「资源链接(asset links)和资源预加载提示(resource hints)」;
- 在嵌入 Vuex 状态进行客户端融合(client-side hydration)时,自动注入以及 XSS 防御。