• SS


    前端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条件判断

  • 相关阅读:
    loadrunner-3-19LR常见函数
    loadrunner-3-18Service-Level Agreement(服务水平协议)
    loadrunner-3-15IP欺骗
    loadrunner-3-14集合点
    Python 静态类型检查 mypy 示例
    JavaScript 中 == 和 === 的区别
    Python 一键安装全部依赖包
    TypeError: 'NoneType' object is not subscriptable
    前端开发神器 VSCode 使用总结
    Next.js 配置接口跨域代理转发
  • 原文地址:https://www.cnblogs.com/likeFlyingFish/p/6143363.html
Copyright © 2020-2023  润新知