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 函數, 這些均可以嘗試一下。