zoukankan      html  css  js  c++  java
  • 浅谈 Web 中前后端模板引擎的使用

    浅谈 Web 中前后端模板引擎的使用

    一、总结

    1、模板引擎:就是用来操作模板的引擎,就是用来渲染模板的,模板就是页面,就是用来生成页面的,其实具体的就是使用户界面与业务数据(内容)分离

    2、模板引擎的作用:使前端页面也前端逻辑代码(业务数据)不再混合,便于阅读和修改以及简单错误

    3、模板引擎的实质:函数,用来实现前端页面也前端逻辑(业务数据)代码的分离

    4、ajax:ajax的出现使前后端分离成为可能。

    二、模板引擎是什么(百度)

    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。 

    概念

    编辑
    模板引擎不属于特定技术领域,它是跨领域跨平台的概念Asp下有模板引擎,在PHP下也有模板引擎,在C#下也有,甚至JavaScriptWinForm开发都会用到模板引擎技术

    原理

    编辑
    模板引擎的实现方式有很多,最简单的是“置换型”模板引擎,这类模板引擎只是将指定模板内容(字符串)中的特定标记(子字符串)替换一下便生成了最终需要的业务数据(比如网页)
    置换型模板引擎实现简单,但其效率低下,无法满足高负载的应用需求(比如有海量访问的网站),因此还出现了“解释型”模板引擎“编译型”模板引擎等。

    用途

    编辑
    模板引擎可以让(网站)程序实现界面与数据分离业务代码与逻辑代码的分离,这就大大提升了开发效率,良好的设计也使得代码重用变得更加容易。
    我们司空见惯的模板安装卸载等概念,基本上都和模板引擎有着千丝万缕的联系。模板引擎不只是可以让你实现代码分离(业务逻辑代码和用户界面代码),也可以实现数据分离(动态数据与静态数据),还可以实现代码单元共享(代码重用),甚至是多语言、动态页面静态页面自动均衡(SDE)等等与用户界面可能没有关系的功能。

    三、浅谈 Web 中前后端模板引擎的使用

    后端 MVC

    说起模板渲染,楼主首先接触的其实并不是前端模板引擎,而是后端。后端 MVC 模式中,一般从 Model 层中读取数据,然后将数据传到 View 层渲染(渲染成 HTML 文件),而 View 层,一般都会用到模板引擎,比如楼主项目中用到的 PHP 的 smarty 模板引擎。随便上段代码感受一下。

    <div>
      <ul class="well nav nav-list" style="height:95%;">
        {{foreach from=$pageArray.result item=leftMenu key=key name=leftMenu}}
          <li class="nav-header">{{$key}}</li>
          {{foreach from=$leftMenu key=key2 item=item2}}
            <li><a target="main" href='{{$item2}}'>{{$key2}}</a></li>
          {{/foreach}}
        {{/foreach}}
      </ul>
    </div>

    传入 View 层的其实就是个叫做 $pageArray 的 JSON 数据。而 MVC 模式也是非常容易理解,然后再看看下面这张图。

    以前的 WEB 项目大多会采用这种后台 MVC 模式,这样做有利于 SEO,并且与前端请求接口的方式相比,少了个 HTTP 请求,理论上加载速度可能会稍微快些。但是缺点也非常明显,前端写完静态页面,要让后台去「套模板」,每次前端稍有改动,后台对应的模板页面同时也需要改动,非常麻烦。页面中如果有复杂的 JS,前端写还是后端写?前端写的话,没有大量的数据,调试不方便,后端写的话... 所以楼主看到的 PHPer 通常都会 JS。

    前端模板

    AJAX 的出现使得前后端分离成为可能。后端专注于业务逻辑,给前端提供接口,而前端通过 AJAX 的方式向后端请求数据,然后动态渲染页面

    我们假设接口数据如下:

    [{name: "apple"}, {name: "orange"}, {name: "peach"}]

    假设渲染后的页面如下:

    <div>
      <ul class="list">
        <li>apple</li>
        <li>orange</li>
        <li class="last-item">peach</li>
      </ul>
    </div>

    前端模板引擎出现之前,我们一般会这么做:

    <div></div>
    <script>
    // 假设接口数据
    var data = [{name: "apple"}, {name: "orange"}, {name: "peach"}];
    
    var str = "";
    str += '<ul class="list">';
    
    for (var i = 0, len = data.length; i < len; i++) {
      if (i !== len - 1)
        str += "<li>" + data[i].name + "</li>";
      else
        str += '<li class="last-item">'  + data[i].name + "</li>";
    }
    
    str += "</ul>";
    document.querySelector("div").innerHTML = str;
    </script>

    其实楼主个人也经常这么干,看上去简单方便,但是这样做显然有缺点,将 HTML 代码(View 层)和 JS 代码(Controller 层)混杂在了一起,UI 与逻辑代码混杂在一起,阅读起来会非常吃力。一旦业务复杂起来,或者多人维护的情况下,几乎会失控。而且如果需要拼接的 HTML 代码里有很多引号的话(比如有大量的 href 属性,src 属性),那么就非常容易出错了(这样干过的应该深有体会)

    这个时候,前端模板引擎出现了,Underscore 的 _.template 可能是最简单的前端模板引擎了(可能还上升不到引擎的高度,或者说就是个前端模板函数)。我们先不谈 _.template 的实现,将以上的代码用其改写。

    <div></div>
    <script src="//cdn.bootcss.com/underscore.js/1.8.3/underscore.js"></script>
    <script type="text/template" id="tpl">
      <ul class="list">
        <%_.each(obj, function(e, i, a){%>
          <% if (i === a.length - 1) %>
            <li class="last-item"><%=e.name%></li>
          <% else %>
            <li><%=e.name%></li>
        <%})%>
      </ul>
    </script>
    
    <script>
    // 模拟数据
    var data = [{name: "apple"}, {name: "orange"}, {name: "peach"}];
    
    var compiled = _.template(document.getElementById("tpl").innerHTML);
    var str = compiled(data);
    document.querySelector("div").innerHTML = str;
    </script>

    这样一来,如果前端需要改 HTML 代码,只需要改模板即可。这样做的优点很明显,前端 UI 和逻辑代码不再混杂,阅读体验良好,改动起来也方便了许多

    前后端分离最大的缺点可能就是 SEO 无力了,毕竟爬虫只会抓取 HTML 代码,不会去渲染 JS。(PS:现在的 Google 爬虫已经可以抓取 AJAX 了 Making AJAX applications crawlable ,具体效果未知)

    Node 中间层

    单纯的后端模板引擎(后端 MVC)以及前端模板引擎方式都有一定的局限性,Node 的出现让我们有了第三种选择,让 Node 作为中间层。

    具体如何操作?简单地说就是让一门后台语言(比如 Java?PHP?)单纯提供渲染页面所需要的接口,Node 中间层用模板引擎来渲染页面,使得页面直出。这样一来,后台提供的接口,不仅 Web 端可以使用,APP,浏览器也可以调用,同时页面 Node 直出也不会影响 SEO,并且前后端也分离,不失为一种比较完美的方案。

  • 相关阅读:
    Button
    启动活动最佳写法
    随时随地退出程序
    知晓当前是在哪个活动
    Failed to resolve:com.android.support:appcompat-v7:报错处理
    未能从程序集“System.ServiceModel”中加载类型“System.ServiceModel.Activation.HttpModule”
    office文档图标不正常显示
    feign和ribbon的异常捕捉
    rocketMQ为什么会重复消费
    springboot时区问题
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/9004047.html
Copyright © 2011-2022 走看看