Vue实现SSR效果
SSR概念
SSR即通过服务端渲染生成后输出给客户端。在SPA之前我们的WEB架构大都是SSR,如WordPress、DEDECMS、Discuz等,都是通过服务端取出数据和模板组合生成html输出给前端,且路由是在服务端控制的。
为什么要使用SSR
首屏优化 非SPA页面后台渲染好了直接返回HTML给浏览器,浏览器直接展示页面。而SPA页面后台给浏览器返回一堆js,前台再执行js去渲染页面,就导致打开很慢。
有助于seo 搜索引擎会通过蜘蛛发http get请求的方式去访问你的网页,并根据网站的内容来建立索引。蜘蛛是不会用js来渲染页面然后再爬里面的内容的,它们通常就是爬一个html文件。因此SPA页面就凉凉了。
SSR的实现原理和缺陷
使用SSR渲染是为了解决单页面应用SEO能力不足的问题。所有的操作仍然是单页面控制,所谓的服务端渲染只是在平时返回的单页面应用的html上增加了对应路由的页面信息,好让爬虫获取到而已。
所以SSR项目需要服务端渲染和客户端渲染,服务端渲染就是根据vue实例获取对应路由的SEO信息并添加到单页面应用的HTML上,客户端渲染就是平时我们所熟悉的单页面应用。
vue-server-renderer
将Vue实例渲染成html
构建服务器端渲染我们需要借助vue-server-renderer,为了了解它的作用,我们先看一段代码(先安装vue和vue-server-renderer,yarn add vue vue-server-renderer,vue-server-renderer和vue必须匹配版本):
const Vue = require('vue')
const app = new Vue({
template: `<div>hello world</div>`
})
const renderer = require('vue-server-renderer').createRenderer()
renderer.renderToString(app,(err, html)=>{
if(err) throw err
console.log(html)
})
执行node server.js可以看到打印<div>Hello World</div>,从这段代码可以明白vue-server-renderer的作用是拿到Vue实例并渲染成html
将html代码渲染到页面上
为了将代码渲染到页面上,我们需要构建一个服务(官方使用的是express,也可以使用koa),接下来我们对上面的server.js进行改造(安装express,yarn add express)。
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*',(req, res)=>{
const app = new Vue({
template: `<div>hello world</div>`
})
renderer.renderToString(app,(err, html)=>{
if(err){
res.status(500).end('Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
})
})
server.listen(8080)
执行node server.js并在浏览器上打开localhost:8080,页面上显示hello world说明服务已经启动。
1、使用页面模板
创建一个页面模板index.template.html,内容如下,<!--vue-ssr-outlet-->这里将是应用程序 HTML 标记注入的地方
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
const renderer = createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})
2、模板插值
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
const renderer = createRenderer({
template: require('fs').readFileSync('./index.template.html', 'utf-8')
})本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!