cli+express手把教你搭建SSR(3)

初始的目录结构已经搭建好了之后,接下来需要继续向下进行,首先要做的就是要在router目录中添加一个index.js文件,用来创建路由信息(在使用路由的时候一定要确保路由已经安装)。路由在项目中所起到的作用应该是重要的,路由会通过路径把页面和组件之间建立联系,并且一一的对应起来,完成路由的渲染。

接下来在router下面的index.js文件中写入如下配置:

const vueRouter = require("vue-router"); const Vue = require("vue"); Vue.use(vueRouter); modul.exports = () => { return new vueRouter({ mode:"history", routers:[ { path:"https://www.jb51.net/", component:{ template:`<h1>这里是首页<h1/>` }, name:"home" }, { path:"/about", component:{ template:`<h1>这里是关于页<h1/>` }, name:"about" } ] }) }

上面的代码中,仔细观察的话,和平时在vue-cli中所导出的方式是不一样的,这里采用了工厂方法,这里为什么要这样?记得在雏形里面说过,为了保证用户每次访问都要生成一个新的路由,防止用户与用户之间相互影响,也就是说Vue实例是新的,我们的vue-router的实例也应该保证它是一个全新的。

现在Vue实例和服务端混在一起,这样对于项目的维护是很不好的,所以也需要把Vue从服务端单独抽离出来,放到app.js中去。这里采用和router同样的方式使用工厂方式,以保证每次被访问都是一个全新的vue实例。在app.js导入刚刚写好的路由,在每次触发工厂的时候,创建一个新的路由实例,并绑定到vue实例里面,这样用户在访问路径的时候无论是vue实例还是router都是全新的了。

app.js:

const Vue = require("vue"); const createRouter = require("./router") module.exports = (context) => { const router = createRouter(); return new Vue({ router, data:{ message:"Hello,Vue SSR!" }, template:` <div> <h1>{{message}}</h1> <ul> <li>, <router-link to="https://www.jb51.net/">首页<router-link/> </li> <li> <router-link to="/about">关于我<router-link/> </li> </ul> </div> <router-view></router-view> ` }); }

做完这些东西貌似好像就能用了一样,但是还是不行,仔细想想好像忘了一些什么操作,刚刚把vue实例从index.js中抽离出来了,但是却没有在任何地方使用它,哈哈,好像是一件很尴尬的事情。

修改index.js文件:

const express = require("express"); const vueApp = require("./src/app.js"); const vueServerRender = require("vue-server-render").creteRender(); const app = express(); app.get('*',(request,respones) => { // 这里可以传递给vue实例一些参数 let vm = vueApp({}) respones.status(200); respones.setHeader("Content-Type","text/html;charset-utf-8;"); vueServerRender.renderToString(vm).then((html) => { respones.end(html); }).catch(error => console.log(error)); }) app.listen(3000,() => { console.log("服务已启动") });

准备工作都已经做好啦,完事具备只欠东风啦。现在运行一下npm start可以去页面上看一下效果啦。看到页面中已经渲染出来了,但是好像是少了什么?虽然导航内容已经都显示出来了,但是路由对应的组件好像没得渲染噻。具体是什么原因导致的呢,vue-router是由前端控制渲染的,当访问路由的时候其实,在做首屏渲染的时候并没有授权给服务端让其去做渲染路由的工作。(⊙﹏⊙),是的我就是这么懒...

这个问题解决方案也提供了相对应的操作,不然就知道该怎么写下去了。既然在做渲染的时候分为服务端渲染和客户端渲染两种,那么我们就需要两个入口文件,分别对应的服务端渲染的入口文件,另个是客户端渲染的入口文件。

在src文件夹下面添加两个.js文件(当然也可以放到其他地方,这里只是为了方便),entry-client.js这个文件用户客户端的入口文件,entry-server.js那么这个文件则就作为服务端的入口文件。既然入口文件已经确定了,接下来就是要解决刚才的问题了,首先解决的是服务端渲染,在服务端这里需要把用户所访问的路径传递给vue-router,如果不传递给vue-router的话,vue-router会一脸懵逼的看着你,你什么都不给我,我怎么知道渲染什么?

在entry-server中需要做的事情就是需要把app.js导入进来,这里可以向上翻一下app.js中保存的是创建vue实例的方法。首先在里面写入一个函数,至于为什么就不多说了(同样也是为了保证每次访问都有一个新的实例),这个函数接收一个参数([object]),由于这里考虑到可能会有异步操作(如懒加载),在这个函数中使用了Promise,在Promise中首先要拿到连个东西,不用猜也是能想到的,很重要的vue实例和router实例,so~但是在app中好像只导出了vue实例,还要根据当前所需要的去更改app.js。

app.js:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/8b6db41a529668b00d78180a807ff1c9.html