ssr服务器渲染
安装vue和vue-server-renderer
npm install vue vue-server-renderer --save
2.创建vue实例,使用renderer解析
// 创建vue实例 const Vue = require("vue"); const app = new Vue({ template: `<div>hellow world</div>`, }); // 创建一个renderer const renderer = require("vue-server-renderer").createRenderer(); // 将实力渲染成HTML // renderer.renderToString(app,(err,html)=>{ // if (err) throw err; // console.log(html) // }) // 2.5.0++ 不传入回调函数 renderer .renderToString(app) .then((html) => { console.log(html); }) .catch((err) => { console.log(err); });
与服务器集成
安装express
npm install express --save
启用一个服务,访问任何页面都只返回一个renderer.renderToString方法将vue实例app转换成的html
const Vue = require("vue"); const server = require("express")(); const renderer = require("vue-server-renderer").createRenderer(); /** * req 请求对象 * res 响应对象 */ server.get("*", (req, res) => { const app = new Vue({ data() { return { url: req.url, }; }, template: `<div>访问的URL是:{{url}}</div>`, }); renderer .renderToString(app) .then((html) => { res.end(` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello</title> </head> <body>${html}</body> </html> `); }) .catch((err) => { res.status(500).end("Internal Server Error"); }); }); server.listen(8000, () => { console.log("服务启动在localhost:8000..."); });
renderer创建时传入模板,将来自动将内容渲染到模板中标签上
模板中支持插值表达式,{{{}}}表示不用转义,{{}}会做转义处理
const renderer = require('vue-server-renderer').createRenderer({ template: require('fs').readFileSync('./index.template.html', 'utf-8') }) renderer.renderToString(app, (err, html) => { console.log(html) // html 将是注入应用程序内容的完整页面 })
template中的值来源于renderer.toString执行传入的第二个参数
const context={ title:"这是注入的title", meta: ` <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> ` } //执行时传入即可 renderer .renderToString(app,context) .then((html) => { console.log(html) res.end(html); }) .catch((err) => { res.status(500).end("Internal Server Error"); });
完整代码
const Vue = require("vue"); const server = require("express")(); const template = require("fs").readFileSync("./index.template.html", "utf-8"); const renderer = require("vue-server-renderer").createRenderer({ template, }); const context = { title: "这是注入的title", meta: ` <meta name="keyword" content="vue,ssr"> <meta name="description" content="vue srr demo"> `, }; /** * req 请求对象 * res 响应对象 */ server.get("*", (req, res) => { const app = new Vue({ data() { return { url: req.url, }; }, template: `<div>访问的URL是:{{url}}</div>`, }); renderer .renderToString(app, context) .then((html) => { res.end(html); }) .catch((err) => { res.status(500).end("Internal Server Error"); }); }); server.listen(8000, () => { console.log("服务启动在localhost:8000..."); });
编写通用代码
服务器的数据的响应式
因为代码在服务器端,希望每次访问都是一个新的实例,因为服务器端来说,每个请求都是一次新的服务,
实际渲染过程中需要确定性,我们要在服务器上预取数据,这意味着,服务器端的响应式是多于的,默认禁用,省了些性能开销
生命周期的执行位置
beforeCreate/created在服务器端执行,这些方法中不要使用setInterval,可以在beforeMount/mounted中设置,在beforeDestroy 或者destroy中销毁
作者:xin_满眼xin辰
链接:https://www.jianshu.com/p/495b8abb459f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。