vue SSR
1、SSR
SSR:服务端渲染,页面在服务端渲染后返回给前端,使用SSR可以加速首屏渲染,有利于SEO优化。
缺陷:
- 占用很多服务器内存
- 浏览器API无法正常使用,因为node只能获取到vue实例,但是又只是进行字符串的拼接,无法知道DOM挂载等信息,所以只能拿到
beforeCreate \ created
两个钩子,所以服务端渲染的请求需要在create
里面发起请求 - vue里DOM相关api都无法使用
- 需要在node.js服务环境中运行
流程图:
把一份代码打包出服务器端和客户端两份代码,服务端代码返回一串没有交互能力的字符串,然后再把客户端打包的代码注入到服务端返回的代码中。
2、vue SSR
官网地址:https://ssr.vuejs.org/zh/
vue实现了可以在node中解析vue,将实例渲染成一个字符串,将字符串返回前端,前端进行渲染。
安装依赖
npm install vue vue-server-renderer koa @koa/router
写./server.js
代码,进行服务端渲染
const Vue = require('vue');
const VueServerRenderer = require('vue-server-renderer');
const Koa = require('koa');
const Router = require('@koa/router');
let app = new Koa();
let router = new Router();
let render = VueServerRenderer.createRenderer();
let vm = new Vue({
data() {
return {
name: '测试,服务端vm.data的数据'
}
},
template: '<div></div>'
})
app.use(router.routes());
router.get('/', async(ctx) => {
ctx.body = await render.renderToString(vm)
})
app.listen(3000)
执行代码,访问localhost:3000
,可以看到返回的数据
返回的没有HTML的基础结构,我们可以使用模板进行渲染
新建一个模板./temp.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>Document</title>
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
<!--vue-ssr-outlet-->
就是服务端渲染进行替换的地方
修改服务端的代码
const fs = require('fs');
const template = fs.readFileSync('./temp.html', 'utf8');
let render = VueServerRenderer.createRenderer({
template: template
});
然后重新运行代码,访问页面查看源代码就可以看到如下代码了。
<!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>Document</title>
</head>
<body>
<div data-server-rendered="true">测试,服务端vm.data的数据</div>
</body>
</html>
3、前后端打包
在上面的代码里面,如果我们有多个用户一起请求,其实使用的还是一个实例。
我们可以通过把构造函数抽离到app.js
,然后返回一个函数,在函数里new 来解决。
// app.js
const Vue = require('vue');
module.exports = function createApp (context) {
return new Vue()
}
// server.js
const createApp = require('./app')
let vm = createApp();
这样不同的用户进来就都是一个全新的实例,不再是单例了。
app.js
简单的导出一个实例,我们的服务端和客户端也可以引用来写不同的代码,在服务端进行渲染,在客户端进行挂载DOM