[聊一聊系列] 聊一聊前端模板与渲染那些事儿
欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码):
https://segmentfault.com/blog/frontenddriver
作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板。我们今天就来聊聊,拼装与渲染模板的那些事儿。
如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力。
1 页面级的渲染
在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串。浏览器对其进行渲染。html中可能会混有一些php(或者php中混有一些html)。在服务端将数据与模板进行拼装,生成要返回浏览器端的html串。
这与我们现在做一个普通网页没什么区别。只不过现在,我们更常使用模板技术来解决前后端耦合的问题。
前端使用模板引擎,在html中写一些标签,与数据与逻辑基本无关。后端在渲染的时候,解析这些标签,生成HTML串,如smarty。其实前端与后端的交互在服务端就已经有一次了。
模板:
front.tpl {%$a%}后端:// 设置变量$smarty->assign('a', 'give data');// 展示模板$smarty->display("front.tpl");到前端时是渲染好的html串: give data
这种方式的特点是展示数据快,直接后端拼装好数据与模板,展现到用户面前。
2 异步的请求与新增模板
新的时代,由ajax引领。(Asynchronous Javascript And XML),这种技术的历史,我就不再赘述。ajax的用法也有多种。
ajax接受各种类型的返回。包括XML/JSON/String等。前端发起ajax请求,后端直接将数据返回。
但是,读者们有没有想过,ajax回来的数据是干嘛用的呢?相信大部分人使用ajax拿回的数据是用来展示的。前端得把ajax拿回来的数据与模板进行拼装。这就面临了一个问题,当你的模板非常“华丽”的时候(也就是模板代码比较多的时候)。我们在前端写的拼字符串的逻辑,会非常的复杂。
也有的人图省事,直接就在ajax的返回值中,传输拼装好的html字符串。这样可以直接把ajax拿到的html字符串,填充到页面上。
下面实例说明一下两种方式:
2.1 ajax获取字符串直接渲染方式
如图2.1.1所示:
index.html # 下面是待填充区域: var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status ========================================================================a.html## 我是模板这是请求回来的数据
# 下面是待填充区域: var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status '+ res.data+ ''; } }; xhr.open('GET', './b.json'); xhr.send(null);
================================================
b.json
{"data": "这是请求回来的数据"}
![超级产品经理](https://v1cdn.imspm.com/imspm.com超级产品经理2016071322lc5obw44pfb.png) // 这是我们的模板,怎么样,比直接写html字符串拼装看起来清爽多了吧?抱歉,markdown不能并列吧+号写在前面,所以我就写在了后面 var template = '' +''+ '{%=a%}'+ '{%if (a===1){%}'+ ''+ 'a是1'+ ''+ '{%}%}'+ ''; // 能解析输出与if条件语句的函数 function TEMPLATEparser(template, variables) { // 语法替换 var funcStr = template .replace(/\{\%\=(\w+)\%\}/, function (code, variable) { return '"; str += "' + variable + '"; str += "'; }) .replace(/\{\%(if.*?)\%\}(.*?)\{\%(\})\%\}/, function (code, judge, content, end) { return '";' + judge + 'str+="' + content + '";' + end + 'str += "'; }); // 返回拼装函数 return new Function(variables, 'var str = ""; str += "' + funcStr + '";return str;'); } // 实验使用模板引擎去解析并传入变量生成模板 var outHTML = TEMPLATEparser(template, ['a'])(1); document.getElementById('content1').innerHTML = outHTML; outHTML = TEMPLATEparser(template, ['a'])(2); document.getElementById('content2').innerHTML = outHTML;
// 前端需要模板去渲染 include('./template.html')
============================
template.html
前端解析模板的引擎的语法,与后端j解析模板引擎语法一致。这样就达到了一份HTML前后端一起使用的效果。一改俱改,一板两用。其实这样也不算极致的完美,因为聪明的读者会发现,在页面加载的时候,我们多传了一份模板给到前端,如果用户不触发重新渲染的话,可能我们传到前端的模板就算白传了,造成了浪费。聪明的读者们可以考虑一下,如何把这份也给省下去。有的时候,我们需要整片DOM进行更新,比如:
这些html中的节点,需要在某次行为之后,一起被更新。那么我们的js可能会变成这样:
这样的维护,成本极大,还不如直接把整个html重新刷新一遍。这就遇到了我们的js拼装模板了:
但是,直接刷HTML的成本太高。这样浏览器不得不整颗html子树全部重新构建一下,这种方法的性能又不如上一种方法好。好在react给了我们一种新的思路,它用最少的开销帮我们处理模板的更新,却又不用我们维护更新时繁琐的步骤。有兴趣的读者可以了解一下react-web的diff算法及其应用。https://segmentfault.com/a/1190000000606216好了,关于前端常见的模板的拼装与更新,我们就讲到这里,同学们有没有考虑过,自己的项目中,如果有异步请求并渲染的逻辑的时候,采用前端拿数据拼装、前端拿拼装好的模板、混合使用哪种更好呢?文中提及到的例子,均在github上可以找到:聊一聊前端存储那些事儿#html、JavaScript、ajax、架构#
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!