模板引擎

205 阅读1分钟

渲染UI结构时遇到的问题

通过字符拼接或依次改变dom内容的形式el.html(值)来渲染结构比较复杂,维护也很麻烦

<script>

    // 使用jQuery提供的JSONP方法

    $.ajax({

        dataType:'jsonp',//如果发送JSONP请求,必须指定这一项

        url:'http://localhost:3000/api/jsonp',

        success:function(res){

            console.log(res);

            // 渲染dom结构

            var rows = []

            $.each(res.data, function (i, item) {

                rows.push('<li class="list-group-item"> ' + item.a + '</li>')

            })

            $('#cmt-list').empty().append(rows.join(''))

        }

    })

</script>

模板引擎

模板引擎:可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面

优点: 结构清晰,减少字符串拼接,代码易于阅读和维护

art-template

官网

art-template是一个简约、超快的模板引擎

使用步骤

  1. 导入
<script src="./js/template-web.js"></script>
  1. 定义数据
[{ name: 'zs' }]
  1. 定义模板
<script type="text/html" id="search-list">

    <h1>{{name}}</h1>

</script>
  1. 调用 template 函数来渲染dom
let htmlStr=template('search-list', { name: 'zs' })

$('div').html(htmlStr)

标准语法

art-template提供了 {{}} 这种语法格式,在{{}}内可以进行变量输出,或循环数组等操作,这种{{}} 语法在art-template 中被称为标准语法。

输出

//在{{}}语法中,可以输出变量、对象属性、三元表达式、逻辑或、加减乘除等

{{value}}

{{obj.key}}

{{obj['key'}}

{{a?b:c}}

原文输出

//如果要输出的value值中,包含了HTML标签结构,则需要使用原文输出语法,才能保证HTML标签被正常渲染

{{@ value}}



//如果数据是

{ test:<h1>h1</h1> }

//要想通过模版渲染出来

<script type="text/html" id="search-list">

    <h1>{{@ test}}</h1>

</script>

条件输出

//如果需要实现条件输出,则可以在{{}}中使用if...else if.../if的方式,进行按需输出

{{if value}} 按需输出的内容 {{/if}}

{{if v1}} 按需输出的内容 {{else if v2}} 按需输出的内容 {{/if}}



<!-- 模版 -->

<script type="text/html" id="search-list">

    {{if test==1}}test==1

    {{else}}test!=1{{/if}}

</script>

<!-- 调用 template 函数来渲染dom -->

<script>

    let htmlStr=template('search-list', { test: 0 })

    $('div').html(htmlStr)

</script>

循环输出

通过each语法循环数组,当前循环的缩影使用 index进行访问,当前的循环项实用index 进行访问,当前的循环项实用 value 进行访问

{{each arr}}

    {{$index}}{{$value}}

{{/each}}



<!-- 模版 -->

<script type="text/html" id="search-list">

    {{each arr}}

        {{$index}}{{$value.test}}

    {{/each}}

</script>

<!-- 调用 template 函数来渲染dom -->

<script> 

    //传入的数据至少是在对象里,也就是被{}包住

    let htmlStr=template('search-list', { arr: [{ test: 0 }, { test: 1 }] })

    $('div').html(htmlStr)

</script>

过滤器

过滤器的本质就是一个函数,处理一些参数返回需要的值

//定义过滤器

template.defaults.imports.filterName=function(value){/*return处理的结果*/}



//使用

{{value(需要处理的值,传入处理函数中)|filterName(处理函数)}}



<!-- 模版 -->

<script type="text/html" id="search-list">

    {{each arr}}

        {{$index}}{{$value.test|filterName}}

    {{/each}}

    <!-- 结果 02 12 -->

</script>

<!-- 调用 template 函数来渲染dom -->

<script> 

    template.defaults.imports.filterName = function (value) {

        console.log(value);

        value=2; 

        return value 

    } 

    let htmlStr=template('search-list', { arr: [{ test: 0 }, { test: 1 }] })

    // console.log(htmlStr);

    $('div').html(htmlStr)

</script>

实现简易的模版引擎

实现步骤

  1. 定义模版结构
    <script type="text/html" id="tpl-user">

        <div>姓名:{{name}}</div>

        <div>年龄:{{age}}</div>

        <div>性别:{{gender}}</div>

        <div>住址:{{address}}</div>

    </script>
  1. 预调用模板引擎
<script>

    // 定义数据

    let data={

        name:'zs',

        age:23,

        gender:'男',

        address:'北京'

    }

    // 调用模板函数

    let htmlStr=template('tpl-user',data)

    console.log(htmlStr);

    /* 打印结果

    <div>姓名:zs</div>

    <div>年龄:23</div>

    <div>性别:男</div>

    <div>住址:北京</div>

    */

    // 渲染HTML结构

    document.getElementById('user-box').innerHTML=htmlStr

</script>
  1. 封装 template 函数
<script>

    function template(id,data){

        let str=document.getElementById(id).innerHTML

        let pattern=/{{\s*([a-zA-Z]+)\s*}}/

        let patternResult=null

        while((patternResult=pattern.exec(str))){

            str=str.replace(patternResult[0],data[patternResult[1]])

        }

        return str

    }

</script>
  1. 导入并使用自定义的模版引擎