SS - DIY一个前端模板引擎.(一)

发布时间:2017-5-30 21:11:44 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"SS - DIY一个前端模板引擎.(一) ",主要涉及到SS - DIY一个前端模板引擎.(一) 方面的内容,对于SS - DIY一个前端模板引擎.(一) 感兴趣的同学可以参考一下。

前端MVVM 模式有点很多,完全摆脱了意大利面条式的代码。
个人认为,所有MVVM 的框架基础就是一个高性能的JS模板引擎,它极大简化了 DOM 操作, 使页面渲染和业务逻辑彻底分离.
为了理解模板引擎原理(zhaungbi),所以我折腾了一个简化版的模板引擎.可以实现数据绑定,三元表达式, for 循环和 if 判断.
如何实现三元表达式, for 循环和 if 判断,将在下一篇介绍.

HTML 模板

下面是我定义好的html 模板字符串。

var template = `<div>    <span>    {{number}}    </span></div>`;

这是我的数据

var scope ={    number:10}

好了,现在怎么把数据渲染到模板上面呢?

很自然的想到 正则表达式

正则替换

第一步 ,可以使用字符串的replace 函数。
这是正则

   var regex = /\{\{([A-Za-z_\$]+[A-Za-z0-9_\$]*)\}\}/g;

好了,现在编写一个函数,我把我的模板引擎就叫 SS。

var SS = (function() {  var regex = /\{\{([A-Za-z_\$]+[A-Za-z0-9_\$]*)\}\}/g;  var result = "";  var ss = {};  ss.Render = function(template, scope) {    result = template.replace(regex, function(a, b) {      b = b.trim();      return scope[b];    })    return result;  }  return ss;})()

测试一下

SS.Render(template,scope);

这是结果

但是,仅仅渲染一级属性的模板引擎有什么用呢?

渲染多级属性

在这里,渲染多级属性还是分为两种。

  • 变量属性 (不知道这么称是否准确,就是类似于 person.name)
  • 数组属性 (数组元素,key 必须是数字类型)

这里,先解决变量属性

变量属性

首先,需要一个新的正则表达式

      var regex = /\{\{([A-Za-z_\$]+(\.[A-Za-z_\$]+|[A-Za-z0-9_\$])*)\}\}/g;

正则写的很烂,如果发现错误希望不吝赐教

html 模板

var template = `<div>    {{title}}    <ul>        <li>{{item.name}}</li>        <li>{{item.age}}</li>    <ul/><div>`

按照上面模板匹配的数据

var scope = {    title:"hello",   item:{    name:'pawn',age:15    }}

渲染函数

ss.Render = function(template, scope) {    result = template.replace(regex, function($, $1) {        $1 = $1.trim();        var innerdata = scope;        var items = $1.split('.');        for (var i = 0; i < items.length; i++) {            innerdata = innerdata[items[i]];        }        return innerdata;    });    return result;}

在这里考虑到元素的属性,所以将{{}} 中包含字符'.' 也匹配出来,再使用'.'分割,然后依次向下寻找

测试代码

var res = ss.Render(template, scope);console.log(res);

这是结果:

貌似这个模板引擎已经具有雏形了

数组属性

在这里,要是正则能够匹配上[] ,而且里面必须是数字

 var regex = /\{\{([A-Za-z_\$]+(\[\d+\]+|\.[A-Za-z_\$]+|[A-Za-z0-9_$])*)\}\}/g;

这个正则主要是匹配形如 items[0].name 类型.
变量名必须是字母下划线或者$ 符号打头,后面必须是 [],.[A-Za-z_\$] 或者
[A-Za-z0-9_$]

如果正则有错,还忘各位不吝赐教.

形如,items[0].name.a.b 中,可以使用'.' 来分割字符串,然后进行迭代找到最终数据.
在每一次迭代中,可以使用 /[\d+]/.test(items[i]) 来判断是否包含'[]',如果包含,那么使用/[\d+]/循环匹配取出其中每一项.

总体代码就是这样

  ss.Render = function (template, scope) {        result = template.replace(regex, function ($, $1) {            $1 = $1.trim();            var innerdata = scope;            var items = $1.split('.');            for (var i = 0; i < items.length; i++) {                var m;                if (/\[\d+\]/.test(items[i])) {                    innerdata = innerdata[items[i].split('[')[0]];                    var reNumber = /\[(\d+)\]/g;                    while (m = reNumber.exec(items[i])) {                        innerdata = innerdata[m[1]];                    }                }                else {                    innerdata = innerdata[items[i]];                }            }            return innerdata;        });

html 模板

var template =    `<div>    {{title}}    <ul>        <li>           name:{{items[0].name}}           <br />            age:{{items[0].age}}           <br />            sex:{{items[0].sex}}        </li>         <li>           name:{{items[1].name}}           <br />            age:{{items[1].age}}           <br />            sex:{{items[1].sex}}        </li>    <ul/><div>`;

模板数据

var scope = {    title: "person list",    items: [{        name: 'pawn',        age: 21,        sex: 1    }, {            name: 'jk',            age: 30,            sex: 0        },]}

测试

console.log(SS.Render(template, scope));

结果

结束

SS 模板中简单的数据绑定就已经实现.
在 SS 前端模板引擎.(二) 中会插入 三元表达式,for循环和if条件判断


上一篇:如何给Firefox附加组件签名
下一篇:SPI总线(同步)

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。