JavaScript进阶之深入领略数据双向绑定 架构&设计

来源:互联网 / 作者:SKY / 2017-11-25 23:16 / 点击:
对付页面渲染,一样平常分为处事器端渲染和赏识器端渲染。一样平常来说处事器端吐html页面的方法渲染速率更快、更利于SEO,可是赏识器端渲染更利于进步开拓服从和镌汰维
CTO实习营 | 12月3-5日,深圳,是时辰成为优越的技能打点者了

媒介

谈起当前前端最热点的 js 框架,必少不了 Vue、React、Angular,对付大大都人来说,我们更多的是在行使框架,对付框架办理痛点背后行使的根基道理每每存眷不多,近期在研读 Vue.js 源码,也在写源码解读的系列文章。和大都源码解读的文章差异的是,我会实行从一个低级前端的角度入手,由浅入深去讲授源码实现思绪和根基的语法常识,通过一些基本事例一步步去实现一些小成果。

本场 Chat 是系列 Chat 的开篇,我会起首讲授一下数据双向绑定的根基道理,先容比拟一下三大框架的差异实现方法,同时会一步步完成一个简朴的mvvm示例。读源码不是目标,只是一种进修的方法,目标是在读源码的进程中晋升本身,进修根基道理,拓展编码的思想方法。

模板引擎实现道理

对付页面渲染,一样平常分为处事器端渲染和赏识器端渲染。一样平常来说处事器端吐html页面的方法渲染速率更快、更利于SEO,可是赏识器端渲染更利于进步开拓服从和镌汰维护本钱,是一种相干惬意的前后端协作模式,后端提供接口,前端做视图和交互逻辑。前端通过Ajax哀求数据然后拼接html字符串可能行使js模板引擎、数据驱动的框架如Vue举办页面渲染。

在ES6和Vue这类框架呈现早年,前端绑定命据的方法是动态拼接html字符串和js模板引擎。模板引擎起到数据和视图疏散的浸染,模板对应视图,存眷怎样展示数据,在模板外头筹备的数据, 存眷那些数据可以被展示。模板引擎的事变道理可以简朴地分成两个步调:模板理会 / 编译(Parse / Compile)和数据渲染(Render)两部门构成,当今主流的前端模板有三种方法:

String-based templating (基于字符串的parse和compile进程)

Dom-based templating (基于Dom的link或compile进程)

Living templating (基于字符串的parse 和 基于dom的compile进程)

String-based templating

JavaScript进阶之深入明确数据双向绑定

基于字符串的模板引擎,本质上依然是字符串拼接的情势,只是一样平常的库做了封装和优化,提供了更多利便的语法简化了我们的事变。根基道理如下:

典范的库:

art-template

mustache.js

doT

之前的一篇文章中我先容了js模板引擎的实现思绪,感乐趣的伴侣可以看看这里:JavaScript进阶进修(一)—— 基于正则表达式的简朴js模板引擎实现。这篇文章中我们操作正则表达式实现了一个简朴的js模板引擎,操作正则匹配查找出模板中{{}}之间的内容,然后替代为模子中的数据,从而实现视图的渲染。

var template = function(tpl, data) { 

 

  var re = /{{(.+?)}}/g, 

 

    cursor = 0, 

 

    reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g,     

 

    code = 'var r=[];\n'

 

  

 

  // 理会html 

 

  function parsehtml(line) { 

 

    // 单双引号转义,换行符替代为空格,去掉前后的空格 

 

    line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ').replace(/(^\s+)|(\s+$)/g,""); 

 

    code +='r.push("' + line + '");\n'

 

  } 

 

   

 

  // 理会js代码         

 

  function parsejs(line) {   

 

    // 去掉前后的空格 

 

    line = line.replace(/(^\s+)|(\s+$)/g,""); 

 

    code += line.match(reExp)? line + '\n' : 'r.push(' + 'this.' + line + ');\n'

 

  }     

 

     

 

  // 编译模板 

 

  while((match = re.exec(tpl))!== null) { 

 

    // 开始标签  {{ 前的内容和竣事标签 }} 后的内容 

 

    parsehtml(tpl.slice(cursor, match.index)); 

 

    // 开始标签  {{ 和 竣事标签 }} 之间的内容 

 

    parsejs(match[1]); 

 

    // 每一次匹配完成移动指针 

 

    cursor = match.index + match[0].length; 

 

  } 

 

  // 最后一次匹配完的内容 

 

  parsehtml(tpl.substr(cursor, tpl.length - cursor)); 

 

  code += 'return r.join("");'

 

阅读延展

1
3