前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue/react服务端渲染实例

vue/react服务端渲染实例

作者头像
OECOM
发布2020-07-02 11:41:21
8900
发布2020-07-02 11:41:21
举报
文章被收录于专栏:OECOMOECOM

vue和react官方已经给出了服务器渲染的方法,两个框架本身也拥有服务器渲染的相应api,但是无论是next.js还是nuxt.js,还是说网上各种服务器端渲染的方案,个人认为都有很大的局限性,这对于我们快速研发来说很麻烦。

现行服务器渲染缺点

最大的一点就在于前端代码和后端代码耦合过重。他们需要公用一部分生命周期,那么在这些生命周期中有一些对象是在服务器端才有的,有的是在浏览器端才有的,比如window对象等,这在写代码的时候感觉超级不爽,我想在公用生命周期中使用localstorage等这些浏览器端才有的对象,是会直接报错的。

然后学习成本,在语言的使用上,目前网上流行的服务器端渲染采用的方案绝大部分是使用nodejs进行渲染,有的研发不会nodejs只会java,这也会造成一部分的困惑和学习成本。

然后就是代码构成。对于已经构建好的项目如果改成服务器端渲染,修改成本也是非常高的,有时候不亚于重新构建一个。

重构服务器渲染

根据上面提出的一些缺点,我想了一个方案来解决,下面我先来说一下具体实现的思路。

  • 前端代码正常构建,然后打包生成文件,将打包后的文件放到后台渲染服务器的项目中。
  • 后端添加和前端相同的路由,如果前端采用的不是问号加参数的方式(oecom.cn/article?id=123)而是通过动态路由匹配(oecom.cn/article/123),我们可以采用路由匹配的方案来创建后台路由。
  • 根据路由参数去接口服务器或者数据库、redis中查询获得数据,拼接成html,然后返回给页面,如果java则将打包后的index.html修改成jsp页面,通过el表达式渲染,如果是nodejs后台,则采用ejs等模板引擎来渲染
  • 在页面中将服务器返回数据渲染到页面,同时将样式修改为:display:none,以保证用户看不到,但是爬虫可以看到

通过上面的思路想必大家应该明白了,其实这个方案也有一定的使用范围,如果是新闻稿件、个人博客等这种类似文章稿件的网站使用这种方式会特别的简单方便,无需重改前端代码,无须有共享耦合的代码,后台语言也相对比较灵活无论是java还是php还是nodejs都可以使用,前端框架也不局限于vue或react。如果是一个官网页面数据比较复杂,构成部分比较多,需要大量的异步获取,采用这种方案就比较麻烦,所以根据自己的需要酌情使用。

这个方案还有一个优点就是关键字、描述、title都可以进行服务器渲染,增加seo的效果,对于给爬虫看的样式并不需要添加,只是内容堆叠即可。

构建示例

对于前端打包我在这里就不在赘述,我只来说一下打包完成以后的示例,这里采用的依然是nodejs,使用其他语言的小伙伴可自行使用自己语言进行修改,原理都是相同的。

代码语言:javascript
复制
<!doctype html>
<html lang="en">
<head>
    <% if(body) {%>
    <title><%=body?body.title:''%></title>
    <meta name="keywords" content="<%=body?body.keywords:''%>">
    <meta name="description" content="<%=body?body.abstract:''%>">
    <%}%>
    <% if(!body) {%>
    <title></title>
    <%}%>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="/manifest.json">
    <link rel="shortcut icon" id="favIcon" href="/favicon.ico">
    <link href="/static/css/main.c36009f4.css" rel="stylesheet">
</head>
<body>
<% if(body) {%>
<div style="display:none">
    <h1><%=body.title%></h1>
    <div><%-body.content%></div>
    <h2>热门排行</h2>
    <div><%-hostHTML%></div>
</div>
<%}%>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.9c32e239.js"></script>
</body>
</html>

上方代码是一个打包后的完整index页面,我在页面中通过模板语言来进行添加,判断是否有这个返回对象,如果有就进行渲染,渲染的部分样式设置为none,隐藏起来,并不进行多余的样式调整。

再来看一下服务器端的代码

代码语言:javascript
复制
//文章详情页
router.get('/article', function (req, res, next) {
    console.log("访问的是article");
    var params = url.parse(req.url, true).query;
    var pageId = params.pageId.split('_');
    var queryParams = {
        sid: params.sid ? params.sid : pageId[3],
        cid: pageId[1],
        aid: pageId[0]
    }
    common.getArticle(queryParams.sid,queryParams.cid,queryParams.aid, req, function (success, data) {
        if (success) {
               res.render('html', data);
         } else {
                res.render("error");
                return
         }
    }).catch(error=>{
        res.render("error");
    });
});

这部分代码我只是摘取了其中一个路由,并且前端路由采用的是用问号来添加参数的方式,我们后台封装了获取文章稿件的方法,获取成功以后将内容拼接好返回,也就是上面返回的data,如果查询失败这个data就是null,这个data中不仅包含TDK,也包含需要返回的文章稿件内容和热门排行。

添加热门排行的原因是让爬虫在网站中自行按照以后链接进行爬取,加快网页收录速度并增加收录量。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 现行服务器渲染缺点
  • 重构服务器渲染
  • 构建示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档