前言
在了解Vue SSR之前,我们要搞明白两个东西先:SSR
和 浏览器的渲染
,
涉及到的技术:
- Vue
- vue-server-renderer
- Nodejs
- Express
1. 什么是SSR
SSR是Server Side Render
简称;页面上的内容是通过服务端渲染生成的,浏览器直接显示服务端返回的htm
l就可以了。
2. 从输入页面URL到页面渲染完成流程
- 解析URL
- 浏览器本地缓存
- DNS解析
- 建立TCP/IP连接,发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器根据返回的html进行构建DOM树,CSS规则树,如遇到script标签就加载对应的js
开始实践
(1) 第一步: vue-server-renderer
首先我们运用vue-server-renderer
来创建一个文件,通过vue-server-renderer把我们的一个vue实例进行转化为字符串。
我们创建一个文件: server.js
const Vue = require('vue')
const app = new Vue({
template: `<div>Hi Vue SSR!</div>`
})
const renderer = require('vue-server-renderer').createRenderer()
renderer.renderToString(app, (err, html) => {
if(err) throw err
console.log(html)
})
我们用node执行server.js 就会返回html字符串
node server.js
(2) 第二步: 搭建本地服务器,借助express框架
,渲染html
修改一下server.js
const Vue = require('vue')
const express = require('express')
const server = express()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: `<div>Hi Vue SSR! current url: {{url}}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('服务器错误: 500')
return
}
res.end(
`<!DOCTYPE html>
<html lang="en">
<head><title>vue ssr</title></head>
<body>${html}</body>
</html>`
)
})
})
server.listen(8080, () =>{
console.log('服务器已开启: 127.0.0.1:8080')
})
然后执行我们的本地服务器 就可以看到我们的Vue实例渲染在页面上了。
node server.js
按下F12
查看一下html
的编码
现在,我们简单的把一个Vue实例通过SSR渲染在页面上啦。
(3) 扩展: 借助<!--vue-ssr-outlet-->
模板渲染html
首先创建后一个index.template.html
文件,如何必须要在body插入一条注释<!--vue-ssr-outlet-->
<!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>Vue SSR template</title>
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
修改我们的server.js
文件,读取模板,把模板配置到vue-server-renderer
const Vue = require('vue')
const express = require('express')
const vueServerRender = require('vue-server-renderer')
const fs = require('fs')
// 1. 创建本地服务器
const server = express()
// 2. 读取VUE SSR的模板
const template = fs.readFileSync('./index.template.html', 'utf-8')
// 3. 把模板引入到renderer
const renderer = vueServerRender.createRenderer({
template
})
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
// 这里的内容都会插入到<!--vue-ssr-outlet-->注释的下面
template: `<div>Hi Vue SSR! current url: {{url}}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('服务器错误: 500')
return
}
res.end(html)
})
})
server.listen(8080, () =>{
console.log('服务器已开启: 127.0.0.1:8080')
})
打开页面,查看html编码
,已经把我们的内容插入到模板内容的下面
(4)在模板上插值:context
我们在server.js
文件创建一个context上下文变量
,然后传入到renderer的第二个参数
。
const Vue = require('vue')
const express = require('express')
const vueServerRender = require('vue-server-renderer')
const fs = require('fs')
// 1. 创建本地服务器
const server = express()
// 2. 读取VUE SSR的模板
const template = fs.readFileSync('./index.template.html', 'utf-8')
// 3. 把模板引入到renderer
const renderer = vueServerRender.createRenderer({
template
})
// 4. 定义一个上下文
const context = {
title: 'Vue-SSR',
metas: `
<meta name="keyword" content="vue,ssr">
<meta name="description" content="vue-ssr-demo">
`
}
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
// 这里的内容都会插入到<!--vue-ssr-outlet-->注释的下面
template: `<div>Hi Vue SSR! current url: {{url}}</div>`
})
// 传入vue实例,上下文context
renderer.renderToString(app, context, (err, html) => {
if (err) {
res.status(500).end('服务器错误: 500')
return
}
res.end(html)
})
})
server.listen(8080, () =>{
console.log('服务器已开启: 127.0.0.1:8080')
})
注意: index.template.html
文件对于标签的插入,我们是要用三个大括号
,不然插入的内容会被转译为字符串
:
标签两个括号的情况下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
{{metas}}
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
渲染问题
页面渲染的结果:
我们要把标签的插入改为三个大括号
就可以解决:
现在我们已经学会了如何通过Express
,Nodejs
,还有vue-server-renderer
来进行vue的服务端渲染
啦。