1.简介
-
服务器端渲染:Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
-
服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行。
-
服务器端渲染优势:
- 更好的SEO。Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。但是若一开始你的页面是loading状态,之后通过网络请求获取数据,抓取工具不会等待你请求结束后抓取内容,这时你就需要SSR来解决此问题。
- 更快的内容到达时间,可以产生更好的用户体验。
-
服务器端渲染不足:
- 浏览器特定代码,只能在某些生命周期钩子函数中才能使用,外部扩展库需要处理才能够运行。
- 涉及构建和部署的更多要求。服务器端渲染应用程序,需要处于Node.js server运行环境。
- 更多的服务器负载。比仅仅提供静态文件更加占用CPU资源,要准备好服务器负载,并进行合适的缓存。
2.渲染一个Vue实例
2.1 准备工作
- 新建项目 SSR
- yarn init -y 初始化package.json文件
- yarn add vue vue-server-renderer 安装vue和vue-server-renderer
- 新建app.js文件
app.js中
// 第1步:创建一个Vue实例
const Vue = require('vue');
const app = new Vue({
template:`<div>hello SSR!</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)
})
- 执行node app.js 查看打印内容
2.2 与服务器集成
- 在页面中引入Vue,使用vue语法
- 引入express框架
- 引入renderer
const Vue = require('vue'); // 引入Vue,可使用vue语法
const server = require('express')(); // 引入express框架
const renderer = require('vue-server-renderer').createRenderer(); // 引入renderer
server.get('*',(req,res)=>{
// 创建vue实例,定义data,页面template内容
const app = new Vue({
data:{
url:req.url
},
template:`<div>
<h2>访问的URL是:</h2>
<h4 style="color:red">{{url}}</h4>
</div>` // 可以写任意html结构,每次修改时需要重启服务器
})
// renderer
renderer.renderToString(app,(err,html)=>{
if(err){
res.status(500).end('Internal Server Error!')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello SSR</title> // title
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> // 编码
</head>
<body>${html}</body> // 页面内容
</html>
`)
})
})
server.listen(8888)
2.3 使用页面模板
- 定义一个html文件,定义页面中的内容
- 单独在app.js中引入html文件,并使用它
- node 文件.js 查看页面显示内容和终端打印内容
index.template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSR渲染模板</title>
</head>
<body>
<h3>ssr-outlet上面的内容</h3>
<!--vue-ssr-outlet-->
<h2>Hello SSR!</h2>
<p>注意 <!--vue-ssr-outlet--> 注释 -- 这里将是应用程序 HTML 标记注入的地方。</p>
<div style="color: aqua;">
你学废了吗?
</div>
</body>
</html>
app.js
// 渲染单独模板文件中的内容
const Vue = require('vue')
const renderer = require('vue-server-renderer').createRenderer();
const server = require('express')();
server.get('*',(req,res)=>{
const app = new Vue({
template:require('fs').readFileSync('./index.template.html','utf-8'),
})
renderer.renderToString(app,(err,html)=>{
if(err){
res.status(500).end('Internal Server Error!')
return
}
console.log(html) // 打印的HTML是index.template.html中的全部内容
// 结果会将index.template.html文件body中定义的内容展示在页面中
res.end(
`
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello SSR</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>${html}</body>
</html>
`
)
})
})
server.listen(8888);
2.4 模板插值
- index.template.html文件中定义变量,可以插值修改
- app.js中当执行时,将想要插给html的值传送过去
- 在执行node app.js时,终端会打印插值后的结果
index.template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 使用双花括号(double-mustache)进行 HTML 转义插值(HTML-escaped interpolation) -->
<title>{{title}}</title>
<!-- 使用三花括号(triple-mustache)进行 HTML 不转义插值(non-HTML-escaped interpolation) -->
{{{ meta }}}
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
app.js
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 charset="UTF-8">
`
}
server.get('*',(req,res)=>{
const app = new Vue({
data:{
url:req.url
},
template:`<div>访问的URL是: {{url}}</div>`,
});
renderer.renderToString(app,context,(err,html)=>{
console.log(html)
if(err){
res.status(500).end('Internal Server Error!')
return
}
res.end(html)
})
})
server.listen(9999)
使用双花括号形式的插值变量,在模板输出html字符串时是会自动进行字符转义的,这样的目的是为了防止xss攻击等。但是也可以设置不进行转义,就须要用3个花括号的形式定义插值变量
总结用法,希望可以帮助到你,
我是Ably,你无须超越谁,只要超越昨天的自己就好~