在index.js中引入了vue-server-render之后,在使用的时候,我们需要执行一下vue-server-render其中的creteRender方法,这个方法的作用就是会将vue的实例转换成html的形式。
既然有了vue-server-render的方法,接下来就需要引入主角了vue,引入之后然后接着在下面创建一个vue实例,在web端使用vue的时候需要传一些参数给Vue然而在服务端也是如此也可以传递一些参数给Vue实例,这个实例也就是后续添加的那些*.vue文件。为了防止用户访问的时候页面数据不会互相干扰,暂时需要把实例放到get请求中,每次有访问的时候就会创建一个新的实例,渲染新的模板。
creteRender方法能够把vue的实例转成html字符串传递到浏览器。那么接下来由应该怎么做?在vueServerRender方法下面有一个renderToString方法,这个方法就可以帮助我们完成这步操作。这个方法接受的第一个参数是vue的实例,第二个参数是一个回调函数,如果不想使用回调函数的话,这个方法也返回了一个Promise对象,当方法执行成功之后,会在then函数里面返回html结构。
改动如下:
const express = require("express"); const Vue = require("vue"); const vueServerRender = require("vue-server-render").creteRender(); const app = express(); app.get('*',(request,respones) => { const vueApp = new Vue({ data:{ message:"Hello,Vue SSR!" }, template:`<h1>{{message}}</h1>` }); respones.status(200); respones.setHeader("Content-Type","text/html;charset-utf-8;"); vueServerRender.renderToString(vueApp).then((html) => { respones.end(html); }).catch(error => console.log(error)); }) app.listen(3000,() => { console.log("服务已启动") });
上述操作完成之后,一定要记得保存,然后重启服务器,继续访问一下locahost:3000,就会看到在服务端写入的HTML结构了。这样做好像给我们添加了大量的工作,到底与在web端直接使用有什么区别么?
接下来见证奇迹的时刻到了。在网页中右键查看源代码就会发现与之前的在web端使用的时候完全不同,可以看到渲染的模板了。如果细心的就会发现一件很有意思的事情,在h1标签上会有一个data-server-rendered=true这样的属性,这个可以告诉我们这个页面是通过服务端渲染来做的。大家可以去其他各大网站看看哦。没准会有其他的收获。
上面的案例中,虽然已经实现了服务端预渲染,但是会有一个很大的缺陷,就是我们所渲染的这个网页并不完整,没有文档声明,head等等等,当然可能会有一个其他的想法,就是使用es6的模板字符串做拼接就好了啊。确实,这样也是行的通的,但是这个仍是饮鸩止渴不能彻底的解决问题,如果做过传统MVC开发的话,就应该知道,MVC开发模式全是基于模板的,现在这种与MVC有些相似的地方,同理也是可以使用模板的。在dome文件夹下创建index.html,并创建好HTML模板。
模板现在有了该如何使用?在creteRender函数可以接收一个对象作为配置参数。配置参数中有一项为template,这项配置的就是我们即将使用的Html模板。这个接收的不是一个单纯的路径,我们需要使用fs模块将html模板读取出来。
其配置如下:
let path = require("path"); const vueServerRender = require("vue-server-render").creteRender({ template:require("fs").readFileSync(path.join(__dirname,"./index.html"),"utf-8") });
现在模板已经有了,在web端进行开发的时候,需要挂在一个el的挂载点,这样Vue才知道把这些template渲染在哪,服务端渲染也是如此,同样也需要告诉Vue将template渲染到什么地方。接下来要做的事情就是在index.html中做手脚。来通知creteRender把template添加到什么地方。
更改index.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!--vue-ssr-outlet--> </body> </html>
可以发现,在html的body里面添加了一段注释,当将vueServerRender编译好的html传到模板当中之后这个地方将被替换成服务端预编译的模板内容,这样也算是完成一个简单的服务端预渲染了。虽然写入的只是简单的html渲染,没有数据交互也没有页面交互,也算是一个不小的进展了。
使用SSR搭建项目我们继续延续上个项目继续向下开发,大家平时在使用vue-cli搭建项目的时候,都是在src文件夹下面进行开发的,为了和vue项目结构保持一致,同样需要创建一个src文件夹,并在src文件夹创建conponents,router,utils,view,暂定项目结构就这样,随着代码的编写会逐渐向项目里面添加内容。
└─src | ├─components | ├─router | ├─utils | ├─view | └─app.js └─index.js