yarn add express #or npm i express --save
在根目录新建一个 index.js
文件, 内容以下:html
index.jsvue
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。node
Vue-SSR 意思能够解读为将 Vue 对象放在服务端建立。express
安装 vue 与 vue-server-renderer。npm
yarn add vue vue-server-renderer #or npm i vue vue-server-renderer --save
在 express 中渲染一个 Vue 的实例须要 3
步:bash
因此, 打开 index.js 文件,在顶部添加引入app
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> `) }) })
准备好之后从新启动ui
node index.js
访问:http://localhost:3000/vue,便可查看效果。ssr
观察上面的内容不难发现, Vue 实例被渲染后生成的 HTML 并非一个完整的文件,他是须要配合 end 函数中的一大堆字符串 HTML 一块儿工做。
这么一大串 HTML 的字符串写起来但是不太友好。
因此 renderer 对象在建立时能够被指定一个 HTML 模板,这个模板至关于把 end 函数中的那一大串 HTML 字符串提出去了,而且经过约定,将 Vue 实例生成的 HTML 放在约定好的位置。
具体作法以下:
index.template.html
文件。<!--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 接口的定义以下:
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 函数, 这些均可以尝试一下。