首先你需要安装Vue SSR的库,让其能够处理SSR
npm install vue vue-server-renderer --save
然后我们在node 程序中
// 第 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)
})
其重要的步骤可以看为
- 创建Vue实例
- 使用vue-server-renderer的createRenderer方法创建一个renderer
- 使用renderer的renderToString方法将Vue变成一个html
由上面的步骤我们可以得出几个重要的api
createRenderer renderToString。
上面的渲染html我们将得到得是一个div,我们是需要将其插入html文件内才是正确.
renderer.renderToString(app, (err, html) => { // html 为vue实例生成得一段html数据 <div id='app'> </div>
// 需要将其插入html返回才是正确的
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
})
})
上面的方法过于麻烦,我们可以使用createRenderer提供的模板功能。
我们一开始创建renderer的时候,是使用createRenderer(),其没有传入任何参数的。现在我们可以传入一个对象参数。
const renderer = createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8') // { template: '...' } 是使用模板功能
})
renderer.renderToString(app, (err, html) => {
console.log(html) // html 将是注入应用程序内容的完整页面
})
我们来看看模板文件夹的内容
<html>
<head>
<!-- 使用双花括号(double-mustache)进行 HTML 转义插值-->
<title>{{ title }}</title>
<!-- 使用三花括号(triple-mustache)进行 HTML 不转义插值 -->
{{{ meta }}}
</head>
<body>
<!--vue-ssr-outlet--> (注意不要省略掉这个注释,这是必不可少的插入标记)
</body>
</html>
我们可以通过在renderToString的时候传入一个context进行插值
const context = {
title: 'hello',
meta: `
<meta ...>
<meta ...>
`
}
renderer.renderToString(app, context, (err, html) => {
// 页面 title 将会是 "Hello"
// meta 标签也会注入
})
总结一下api
1. const renderer = require('vue-server-renderer').createRenderer({ template: '...' })
2. renderer.renderToString(app, context, (err, html) => {
...
})