内容简介:为什么要写本文呢,话说现在ssr 的全称是 server side render,服务端渲染,vue ssr 的意思就是在服务端进行 vue 的渲染,直接对前端返回带有数据,并且是渲染好的HTML页面;而不是返回一个空的HTML页面,再由vue 通过异步请求来获取数据,再重新补充到页面中。这么做的最主要原因,就是搜索引擎优化,也就是SEO,这更利于网络爬虫去爬取和收集数据。
为什么要写本文呢,话说现在 vue-ssr 官网 上对 vue 服务端渲染的介绍已经很全面了,包括各种服务端渲染框架比如 Nuxt.js 、 集成 Koa 和vue-server-renderer 的 node.js 框架 egg.js,都有自己的官网和团队在维护,文档真是面面俱到功能强大,但是,我个人在刚开始看这些资料的时候,总是忍不住发起灵魂三问:“我是谁?我在哪?我在干什么?”,提前没有相关知识的人开始学这些,肯定是要走一些弯路或者卡在某个点一段时间的,所以我想把我的学习经验做下总结,一方面方便自己以后查阅,一方面也会在文中加一些针对官网上没有细说的点的理解,希望能帮助你减少些学习成本,毕竟这是一个知识共享的时代嘛。本文不涉及到源码解析,主要讲解如何实现 vue 的服务端渲染,比较适合 vue-ssr 小白阅读,下面我们进入正文:
先说下基本概念:
ssr 的全称是 server side render,服务端渲染,vue ssr 的意思就是在服务端进行 vue 的渲染,直接对前端返回带有数据,并且是渲染好的HTML页面;而不是返回一个空的HTML页面,再由vue 通过异步请求来获取数据,再重新补充到页面中。
这么做的最主要原因,就是搜索引擎优化,也就是SEO,这更利于网络爬虫去爬取和收集数据。
为什么这样就有利于网络爬虫爬取呢?
这里简单说一下爬虫的爬取方式,爬虫通过访问 URL 获取一个页面后,会获取当前HTML中已存在的数据,也可以理解为把拿到的 HTML 页面转为了字符串内容,然后解析、存储这些内容,但是如果页面中有些数据是通过异步请求获得的,那么爬虫是不会等待异步请求返回之后才结束对页面数据的解析的,这样就会没有爬取到这部分数据,很不利于其他搜索引擎的收录。
这也就是为什么单页面网站是不具备良好的SEO效果的,因为单页面返回的就是一个基本为空的 HTML 文件,里面就一个带有ID的元素等待挂载而已,页面的内容都是通过 js 后续生成的,比如这样:
<!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body><div id="app"></div></body> <script src="bundle.js"></script> </html>
但对于很多公司来说,公司的产品是希望能被百度、谷歌等搜索引擎收录之后,进行排名,进一步的被用户搜索到,能更利于品牌的推广、流量变现等操作,要实现这些,就必须保证产品的网页是能够被网络爬虫爬取到的,显然一个完整的带有全部数据的页面更利于爬虫的爬取,当然现在也有很多方法可以去实现针对页面异步数据的爬取,github 上也开源了很多的爬虫代码,但是这显然对于爬虫来说更加的不友好、成本更高。
SSR 当然也是有着其他的好处的,比如首屏页面加载速度更快,用户等待时间更短等,其他更多概念可以查看官网 https://ssr.vuejs.org/zh/ ,这些官网上都有介绍。
代码实现
下面我们结合官网上的代码,做一下代码实操,来加深下理解:
在官网中,提供了一个使用模块 vue-server-renderer 简单实现 vue 服务端渲染的示例:
新建一个文件夹vue-ssr-demo,进入其中执行如下命令:
// 安装模块 npm install vue vue-server-renderer --save
创建文件 server.js
// vue-ssr-demo/server.js 示例代码 //第一步,创建vue实例 const Vue = require('vue'); const app = new Vue({ template: "<div>hello world</div>" }); //第二步,创建一个renderer const renderer = require('vue-server-renderer').createRenderer(); //第三步,将vue渲染为HTML renderer.renderToString(app, (err, html)=>{ if(err){ throw err; } console.log(html); });
保存以上代码后,在 vue-ssr-demo 文件夹下打开命令行工具,执行 node server.js 命令,可得到如下 HTML 内容:
➜ vue-ssr-demo node server.js
好,上面的例子中我们已经让 vue 在服务端,也就是 node 环境下运行起来了,到这里其实已经实现了 vue 的服务端渲染了。
可是,实际项目中使用哪有这么简单,起码数据还没渲染啊,那接下来我们看看如何渲染数据:
vue-ssr 渲染数据的方式有两种,我们先看下第一种:
// server.js const data_vue = { word: 'Hello World!' }; //第一步,创建vue实例 const Vue = require('vue'); //vue 实例化过程中插入数据 const app = new Vue({ data: data_vue, template: "<div>{{word}}</div>" }); //第二步,创建一个renderer const renderer = require('vue-server-renderer').createRenderer(); //第三步,将vue渲染为HTML renderer.renderToString(app, (err, html)=>{ if(err){ throw err; } console.log(html); });
第一种方式,在创建 vue 实例时,将需要的数据传入 vue 的模板,使用方法与客户端 vue 一样;运行 server.js 结果如下,数据 data_vue 已经插入到 vue 模板里面了:
➜ vue-ssr-demo node server.js <div data-server-rendered="true">Hello World!</div>
第二种,模板插值,这里我们也直接先放代码:
const data_vue = { word: 'Hello World!' }; const data_tpl = { people: 'Hello People!' }; //第一步,创建vue实例 const Vue = require('vue'); const app = new Vue({ data: data_vue, template: "<div>{{word}}</div>" }); //第二步,创建一个 renderer 实例 const renderer = require('vue-server-renderer').createRenderer({ template: "<!--vue-ssr-outlet--><div>{{people}}</div>" }); //第三步,将vue渲染为HTML renderer.renderToString(app, data_tpl, (err, html)=>{ if(err){ throw err; } console.log(html); });
这里我们增加了数据 data_tpl,你会发现,在 renderToString 方法中传入了这个参数,那么这个参数作用在哪里呢?这就要看下官网中关于 createRenderer 和 renderToString 方法的介绍了,
createRenderer: 使用(可选的)选项创建一个 Renderer 实例。
const { createRenderer } = require('vue-server-renderer')
const renderer = createRenderer({ / 选项 / })
在选项中,就有一个参数叫 template,看官网怎么说的:
template: 为整个页面的 HTML 提供一个模板。此模板应包含注释 <!--vue-ssr-outlet-->,作为渲染应用程序内容的占位符。
为整个页面的 HTML 提供一个模板。此模板应包含注释 <!--vue-ssr-outlet-->,作为渲染应用程序内容的占位符。
模板还支持使用渲染上下文 (render context) 进行基本插值:
使用双花括号 (double-mustache) 进行 HTML 转义插值 (HTML-escaped interpolation);
使用三花括号 (triple-mustache) 进行 HTML 不转义插值 (non-HTML-escaped interpolation)。
根据介绍,在创建 renderer 实例时,可以通过 template 参数声明一个模板,这个模板用来干嘛呢?就用来挂载 vue 模板渲染完成之后生成的 HTML。这里要注意一下,当创建 renderer 实例时没有声明 template 参数,那么默认渲染完就是 vue 模板生成的 HTML;当创建 renderer 实例时声明了 template 参数,一定要在模板中增加一句注释 “<!--vue-ssr-outlet-->” 作为 vue 模板插入的占位符,否则会报找不到插入模板位置的错误。
再次运行 server.js ,结果如下,vue 模板已成功插入,且 template 模板中的 {{people}} 变量也因在 renderToString 方法中第二位参数的传入,显示了数据:
➜ vue-ssr-demo node server.js <div data-server-rendered="true">Hello World!</div><div>Hello People!</div>
如果我们把 template 换成一个 HTML 页面的基本架构,来包裹 vue 模板,是不是就能得到一个完整页面了呢?我们来试一下:
const data_vue = { word: 'Hello World!' }; const data_tpl = { people: 'Hello People!' }; //第一步,创建vue实例 const Vue = require('vue'); const app = new Vue({ data: data_vue, template: "<div>{{word}}</div>" }); //第二步,创建一个renderer const renderer = require('vue-server-renderer').createRenderer({ template: `<!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body> <!--vue-ssr-outlet--><div>{{people}}</div> </body> </html>` }); //第三步,将vue渲染为HTML renderer.renderToString(app, data_tpl, (err, html)=>{ if(err){ throw err; } console.log(html); });
运行 server.js ,结果如下,我们得到了一个完整的 HTML 页面,且成功插入了数据:
➜ vue-ssr-demo node server.js <!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body> <div data-server-rendered="true">Hello World!</div><div>Hello People!</div> </body> </html>
好,现在页面生成了,该怎么显示呢?这里我们借助下框架 Koa 实现,先来安装:
npm install koa -S
然后修改 server.js ,如下:
const data_vue = { word: 'Hello World!' }; const data_tpl = { people: 'Hello People!' }; const Koa = require('koa'); //创建 koa 实例 const koa = new Koa(); const Vue = require('vue'); //创建一个renderer const renderer = require('vue-server-renderer').createRenderer({ template: `<!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body> <!--vue-ssr-outlet--><div>{{people}}</div> </body> </html>` }); // 对于任何请求,app将调用该异步函数处理请求: koa.use(async (ctx, next) => { // await next(); //创建vue实例 const app = new Vue({ data: data_vue, template: "<div>{{word}}</div>" }); //将vue渲染为HTML const body = await renderer.renderToString(app, data_tpl); ctx.body = body; }); // 在端口3001监听: koa.listen(3001); console.log('app started at port 3001...');
运行 server.js :
➜ vue-ssr-demo node server.js app started at port 3001...
然后打开浏览器,输入网址 http://localhost :3001/ ,即可看到运行后的效果。
这样就实现了一个简单的服务端渲染项目,但是我们在平常开发的时候,肯定不会这么简单的去构建一个项目,必然会用到一些,比如打包、压缩的工具,这篇就写到这里,下一篇我们尝试使用 webpack 来构建一个 vue 的服务端渲染项目。
如有问题,欢迎指正!谢谢!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Game Programming Patterns
Robert Nystrom / Genever Benning / 2014-11-2 / USD 39.95
The biggest challenge facing many game programmers is completing their game. Most game projects fizzle out, overwhelmed by the complexity of their own code. Game Programming Patterns tackles that exac......一起来看看 《Game Programming Patterns》 这本书的介绍吧!