Express SSR
yarn add express
#or
npm i express --save
在根目录新建一个 index.js
文件, 内容如下:
index.js
const app = require('express')()
app.get('/', (req, res) => {
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>你好世界!</h1>
</body>
</html>
`)
})
app.listen(3000);
console.info('application is running at: http://localhost:3000');
这时候执行 node .\index.js
是可以访问到你好世界的, 这其实就是 SSR。
Vue-SSR 意思可以解读为将 Vue 对象放在服务端创建。
Express 渲染 Vue
安装 vue 与 vue-server-renderer。
yarn add vue vue-server-renderer
#or
npm i vue vue-server-renderer --save
在 express 中渲染一个 Vue 的实例需要 3
步:
- 创建一个 Vue 实例
- 创建一个 Renderer
- 用 Renderer 渲染 Vue 实例
所以, 打开 index.js 文件,在顶部添加引入
const Vue = require('vue')
const renderer = require('vue-server-renderer').createRenderer()
引入后再添加一个新的路由地址
app.get('/vue', (req, res) => {
// 创建 Vue 实例
const app = new Vue({
data: {
content: 'Hello Vue'
},
template: `
<h1>{{content}}</h1>
`
})
// 使用 renderer 把 Vue 实例渲染为 HTML
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
${html}
</body>
</html>
`)
})
})
准备好以后重新启动
node index.js
访问:http://localhost:3000/vue,即可查看效果。
使用 HTML 模板
观察上面的内容不难发现, Vue 实例被渲染后生成的 HTML 并不是一个完整的文件,他是需要配合 end 函数中的一大堆字符串 HTML 一起工作。
这么一大串 HTML 的字符串写起来可是不太友好。
所以 renderer 对象在创建时可以被指定一个 HTML 模板,这个模板相当于把 end 函数中的那一大串 HTML 字符串提出去了,并且通过约定,将 Vue 实例生成的 HTML 放在约定好的位置。
具体做法如下:
- 在根目录新建
index.template.html
文件。 - 写入基础 HTML。
- 在想要渲染 Vue 实例的位置贴上
<!--vue-ssr-outlet-->
这个注释。
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
注意:<!--vue-ssr-outlet-->
不可以有空格
然后修改 index.js 文件的 createRenderer 函数:
const renderer = require('vue-server-renderer').createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
修改 /vue
路由:
app.get('/vue', (req, res) => {
const app = new Vue({
data: {
content: 'Hello Vue'
},
template: `
<h1>{{content}}</h1>
`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
重新启动
node index.js
访问:http://localhost:3000/vue, 看起来一切正常。
关于 Renderer
Renderer 接口的定义如下:
interface Renderer {
renderToString(vm: Vue, callback: RenderCallback): void;
renderToString(vm: Vue, context: object, callback: RenderCallback): void;
renderToString(vm: Vue): Promise<string>;
renderToString(vm: Vue, context: object): Promise<string>;
renderToStream(vm: Vue, context?: object): Readable;
}
renderToString 具有 4 个重载,另外还有一个 renderToStream 函数, 这些都可以尝试一下。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。