模板引擎art-template的介绍

一 简介 art-template:

下载地址:https://github.com/aui/art-template

通常所说的渲染分为:

//1. 浏览器端渲染
		//对应 template-web.js

//2.服务器端渲染
     //对应  npm install art-template --save
    //对应的express框架 		npm install  express-art-template --save

二 模板语法:

art-template 支持标准语法与原始语法。标准语法可以让模板易读写,而原始语法拥有强大的逻辑表达能力。标准语法支持基本模板语法以及基本 JavaScript 表达式;原始语法支持任意 JavaScript 语句,这和 EJS 一样。

2.1 输出语法:

// {{@ value }} <%= value %>
//标准语法输出字符串
<td class="text-center">{{@ "已发布" }}</td>

//原始语法输出字符串
<td class="text-center"><%= "已发布" %></td>

//输出字符串时要加双引号,否则会当成变量来解析

2.2 分支结构的语法:

//标准语法

{{ if value.status == "published"  }}
        <td class="text-center">{{@ "已发布" }}</td>
{{ else value.status == "drafted" }}
        <td class="text-center">{{@ "草稿" }}</td>
{{ /if }}

//原始语法:
<% if (value.status == "published") { %>   
        <td class="text-center">{{@ "已发布" }}</td>
<% } else(value.status == "drafted") { %>
        <td class="text-center">{{@ "草稿" }}</td>
<% } %>

//原始语法与JS的原生语法很像,只不过多了一对<% %>

2.3 循环分支:

//标准语法的循环
{{each target}}
    {{$index}} {{$value}}
{{/each}}
//$value 与 $index 可以自定义:{{each target val key}}

//1. 自定义的例子:
{{ each list value key }}
    <tr>
      <td class="text-center"><input type="checkbox" index="{{value.id}}"></td>
      <td>{{ value.name }}</td>
      <td>{{ value.slug }}</td>
      <td class="text-center">
      
      	<!-- 这里的onclick就是行内注册事件 -->
        <a href="javascript:void(0);" onclick="editorCategory({{ value.id }})" class="btn btn-info btn-xs">编辑</a>

		<!-- 这里的onclick就是行内注册事件 -->
        <a href="javascript:void(0);" onclick="deleteCategory({{ value.id }})" class="btn btn-danger btn-xs">删除</a>
      </td>
    </tr>
  {{ /each }}

//2. 原始语法与标准语法混用:

<% for(var i =0;i < list.length;i++) { %>
    <tr>
      <td class="text-center"><input type="checkbox" index="{{value.id}}"></td>
      <td>{{ value.name }}</td>
      <td>{{ value.slug }}</td>
      <td class="text-center">
        <a href="javascript:void(0);" onclick="editorCategory({{ value.id }})" class="btn btn-info btn-xs">编辑</a>
        <a href="javascript:void(0);" onclick="deleteCategory({{ value.id }})" class="btn btn-danger btn-xs">删除</a>
      </td>
    </tr>
<% } %>

**//我们发现原始语法与标准语法可以共用,前提是语法书写正确**

这里我们重点强调下,循环语句的语法:

{{ each list value key }}
	......
{{ /each }}

// target 支持 array 与 object 的迭代,其默认值为 $data。

2.3.1 循环语法需要注意的点:

//1. list这个名字可以随便取,也可以叫target,只需要在调用模板的时候,与之对应就
可以了.
//2. 如果遍历的是数组value与key代表一个是数组里的元素,一个是下标.
//3. 如果遍历的是对象value与key代表一个是对象里的属性值,一个是属性名.
//4. list实际上时一个数组,但是我们在模板里面传递的时候,需要将这个数组包一下.
包裹为对象.这是因为文档的规定.

var HTML = template('id' , { ''list'' : arr }); //将arr包裹一下

//5. 如果list是一个对象是一个对象,就不需要包裹,但是传入循环变量里面的list必须是个数组.

var HTML = template('id' , obj); //obj无需包裹
但是模板里面的list必须是obj对象里的数组属性

//6. 在模板里面,如果传入的就是对象,那么直接可以在模板的html代码里直接使用对应的属性与方法.

var HTML = template('id' , obj); //obj无需包裹
//其中的proName,price,oldPrice都是obj对象里面的属性

<script id="tpl-product" type="text/html">
        <div class="product-name">
            名字:
            <span>
               {{ proName }}
            </span>
        </div>
        <div class="product-price">
            价格: 
            <span class="new-price">¥{{ price }}</span>
            <del class="old-price">¥{{ oldPrice }}</del>
        </div>
</script>

比如:
在这里插入图片描述
上面的对象里有result这个数组属性名,所以调用模板时可以直接这样书写:

var HTML = template('id' , obj); //obj无需包裹

//直接将属性名传给模板,模板也会识别这个数组
{{ each result value key }} 
	......
{{ /each }}

至于其他的语法,可以去其官网上查阅文档.

四 客户端模板使用的方法:

4.1 第一,导入模板:

<!-- 1.引入模板引擎 -->
<script src="./JS/template-web.js"></script>

4.2 第二步:准备需要结构类似需要重复生成的模板

<!-- 2.准备模板 -->
<script type="text/html" id="tpl1">
	//这里写需要生成的模板
</script>

4.3 第三步:调用模板的api来渲染模板到页面上

//引用模板,模板生成的内容在变量名ul的内存里面
    var ul = template('tpl1',{ list : 6});

//需要我们追加到页面上去
	document.getElementById('newBd').innerHTML = ul;
/*
	这里需要注意的是,调用api来生成的ul里面包含了需要生成模板里的
	所有内容,但是ul作为一个变量,只是将这些值保存在自己的内存里,
	并没有被解析出来;所以我们又利用innerHTML可以解析标签的功能将
	标签解析出来渲染到页面上
*/

ul里面存放的内容(包含标签)
这里写图片描述
我们可以看到ul里面存放的是一个带有标签的字符串.

五 浏览器端模板需要注意的地方:(最重要)

5.1 因为模板是在页面上的其他元素加载完成之后,才开始加载的,所以一开始页面上没有模板里面的标签,它是后面用引擎渲染上去的.

所有在操作模板里面的标签元素时,我们应该利用 :

 1.行内事件的方法.
 2.事件的委托
 3.等待模板渲染完成后才去获取元素

5.1.1 行内事件获取动态添加的元素

 {{ each list value key }}
    <tr>
      <td class="text-center"><input type="checkbox" index="{{value.id}}"></td>
      <td>{{ value.name }}</td>
      <td>{{ value.slug }}</td>
      <td class="text-center">
      	<!-- 这里的onclick就是行内注册事件 -->
        <a href="javascript:void(0);" onclick="editorCategory({{ value.id }})" class="btn btn-info btn-xs">编辑</a>
        <!-- 这里的onclick就是行内注册事件 -->
        <a href="javascript:void(0);" onclick="deleteCategory({{ value.id }})" class="btn btn-danger btn-xs">删除</a>
      </td>
    </tr>
  {{ /each }}

5.1.2 事件委托获取动态添加的元素

给li的父容器委托一个点击事件,然后由子元素li来触发.这样就可以找到对应的动态添加的子元素.

//以下面的例子举例
<script type="text/html" id="tpl-category-left">
        {{each rows value index}}
            <li class="{{@ index == 0 ? 'active' : '';  }}"><a href="#" data-id="{{@ value.id }}">{{@ value.categoryName }}</a></li>
        {{  /each }}
</script>

//给li标签一个点击事件
//利用事件的委托
$('ul').on('tap','li a',function(){
	//doSomething.......
}

5.2 一个模板里可以有多个渲染对象

这里在模板里面有了两个遍历语法渲染不同的元素,说明,模板里面并不仅仅只能进行一次遍历.

 <!-- 1.模板引擎,轮播图区域 -->
    <script id="tpl-slider" type="text/html">
        <div class="mui-slider-group mui-slider-loop">
            {{each pic value index }}
                {{if index == 0 }}
                    <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="{{ pic[pic.length-1].picAddr }}" /></a></div>
                {{ /if }}
                    <div class="mui-slider-item"><a href="#"><img src="{{ value.picAddr }}" /></a></div>
                    <!--支持循环,需要重复图片节点-->
                {{ if index == pic.length - 1 }}
                    <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="{{ pic[0].picAddr }}" /></a></div>
                {{ /if }}
            {{/each}}
        </div>
        
        <div class="mui-slider-indicator">
            <!-- 默认给第一个小圆点选中 小圆点是有几个就是几个 -->
            <!-- 小圆点 -->
            {{ each pic value key }}
                <div class="mui-indicator {{ key == 0 ? 'mui-active' : '' }}"></div>
            {{ /each }}
        </div>
    </script>

六 服务端渲染

服务端的渲染与客户端的差不多,但是还是有区别(以nodeJS为例):

// 1.  导入包  
		npm install --save art-template
		npm install --save express-art-template
		
// 2.  在html文件使用模板,此时就不需要用script将代码包裹

// 3. 在js文件调用模板

6.1 在html文件使用模板

在html文件中,使用模板语法,将需要循环生成的地方包裹在循环语法里面,注意这里与浏览器端渲染的区别,不需要包裹在script标签中.

<tbody>
            <!-- 这里是一个数组 target是一个数组-->
            {{each target}}
                <tr>
                    <td>{{$index}}</td>
                    <td>{{$value.name}}</td>
                    <td>
                        <a href="javascript:;" onclick="musicPlayer( '{{$value.name}}' )">播放</a>
                    </td>
                </tr>
            {{/each}}
           
 </tbody>

6.2 调用语法

//第一步: 导入包
const template = require('art-template');

//第一个参数是需要渲染的html文件的路径
//第二个参数是一个对象,传给html文件使用模板循环语法中的target
const html = template(__dirname + '/tpl-user.art', {
	//这里的target与html中的名字一致
    user: {
        name: 'aui'
    }
});

例子:

//渲染数据
    var html = template(path.join(__dirname,'../static/html/index.html'), {
        target : musicData
    });
    //设置请求头
    res.setHeader('Content-Type', 'text/html');
    res.end(html);

七 模板的继承

模板的继承一般用在:有些通用的内容可集中放在一个页面文件中,其它要用到这些内容的页面只需要包含(引用)这个通用文件即可。这样便于维护,如果有很多网页,当通用内容需要修改时,只改一个文件就可以了,不需要每个文件单独修改。

最典型的应用比如页脚的版权信息等内容可以放在一个叫做footer.html文件里, 然后其他页面文件在页面内容的最后包含这个文件就可以了

7.1 继承语法:
继承分为两个板块

//1. 被继承的网页,比如:页头,页脚 (父网页)

//2. 继承的网页,比如:这个网页只有中间的主体部分,其他需要继承(子网页)

7.1.1 被继承的网页(父网页)

<!--被继承网页,作者建议用art后缀,但是我们一般不用,还是html-->
<!--layout.art-->
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <!--
    block 表示占位符,头部题目的占位符,表示子网页用实际的
    内容来替换这里,子网页<title>标签里实际内容
    -->
    <title>{{block 'title'}}My Site{{/block}}</title>

	<!--
    block 表示占位符,头部的占位符,表示子网页用实际的
    内容来替换这里,子网页<link>标签里引入自己对应的样式
    -->
    {{block 'head'}}
    <link rel="stylesheet" href="main.css">
    {{/block}}
</head>
<body>
	<!--
    block 表示占位符,body的占位符,表示子网页用实际的
    内容来替换这里body,注意可以不用替换整个body,放在对应的标签内
    就可以了
    -->
    {{block 'content'}}{{/block}}
</body>
</html>

{{block ‘content’}}{{/block}} 代表的含义是用占位符先把内容位置占据,然后在子网页继承的时候用实际的内容与替换就可以了.

7.1.2 继承的网页(子网页)

<!--继承网页,作者建议用art后缀,但是我们一般不用,还是html-->
<!--index.art-->

<!--这句话的目的是引入父网页,注意路径,必须能找到父网页-->
{{extend './layout.art'}}

<!--替换父网页title的内容-->
{{block 'title'}}{{title}}{{/block}}

<!--替换父网页head块的内容-->
{{block 'head'}}
    <link rel="stylesheet" href="custom.css">
{{/block}}

<!--替换父网页body块的内容-->
{{block 'content'}}
<p>This is just an awesome page.</p>
{{/block}}

子网页的作用就是用子网页的实际代码来替换父网页的占位符.相当于父网页只是替你占了位置,但是实际的内容需要子网页来填充.

7.1.3 调用语法渲染

需要被继承的网页模板准备好后,现在我们来调用语法来动态渲染.

// 第一个参数是子页面 parsent.html(需要路径)
// 第二个参数是一个对象需要传输的数据(动态改变子网页的内容的数据)
res.render(path.join(__dirname,'./index.html'), {
    user: {
        name: 'aui'
    }
});

7.2 服务端渲染的例子:

<!--继承自当前目录下的父页面 parsent.html-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
   
   	<!-- 占位 -->
    <title>{{block 'title'}}父网页{{/block}}</title>
  
  	{{block 'head'}}
  		<!-- 占位 -->
    	<link href="/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
	{{/block}}

</head>

<body>
    
            <div class="col-md-9">
                <!-- 中间占位 -->
                {{block 'content'}}{{/block}}
            </div>
        </div>
    </div>
</body>

</html>
<!--这个网页命名为index.html-->

<!--这句话的目的是引入父网页,注意路径,必须能找到父网页-->
{{extend './parsent.html'}}

<!--替换父网页title的内容-->
{{block 'title'}}子网页{{title}}{{/block}}

<!--替换父网页head块的内容-->
{{block 'head'}}
    <link rel="stylesheet" href="head.css">
{{/block}}

<!--替换父网页body块的内容-->
{{block 'content'}}
	<!-- 这里就是动态渲染的数据 -->
	<p>This is my {{ user.name }}.</p>
{{/block}}
// 调用
// 第一个参数是子页面 parsent.html(需要路径)
// 第二个参数是一个对象需要传输的数据(动态改变子网页的内容的数据)
// 注意可以传入多个属性去渲染父页面或则子页面
res.render(path.join(__dirname,'./index.html'), {
    user: {
        name: 'aui'
    }
});

最后 浏览端渲染的实例冒险岛2具体实现代码如下:

效果:
这里写图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./Css/index.css">
    <style>
        .hot-news a {
            position: absolute;
        }
    </style>
</head>
<body>
    <div class="main-area-l">
        <div class="news-box">
            <div class="news-type-box" id="newsBox">
                <div class="news-type-hd clearfix">
                    <div id="newsHd" class="news-type-a cf">
                        <a href="javascript:void(0);" class="" target="_blank">全部</a>
                        <a href="javascript:void(0);" target="_blank" class="">新闻</a>
                        <a href="javascript:void(0);" target="_blank" class="">公告</a>
                        <a href="javascript:void(0);" target="_blank" class="">活动</a>
                        <a href="javascript:void(0);" target="_blank" class="">媒体</a>
                        <a href="javascript:void(0);" target="_blank" class="">玩家</a>
                        <a href="javascript:void(0);" target="_blank" class="active">攻略</a>
                        <span class="tab-arr-line" style="left: 330px;"></span>
                    </div>
                    <a href="#" class="more-link" target="_blank">+</a>
                </div>
                <div class="news-type-bd">
                
                    <div id="newBd" class="news-type-cont">
                        <-- 这里就是模板生成后的内容区域 -->
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

<!-- 1.引入模板引擎 -->
<script src="./jquery-1.12.4.js"></script>
<script src="./JS/template-web.js"></script>


<!-- 2.准备模板 -->
<script type="text/html" id="tpl1">
    <% for(var i=1;i<=list;i++){ %>

        <!-- 默认让第一个显示,其他的都不显示 -->
        {{  if i == 1 }} 
            <!-- 给每一个ul一个点击事件 -->
            <ul class="news-list" style="display: block;"  id="{{@ "ul" }}{{ i }}">
        {{ else  }}
            <ul class="news-list" style="display: none;"  id="{{@ "ul" }}{{ i }}">   
        {{ /if }}
        <li>
            <span class="news-icon "></span>
            <!-- 为了便于区分这里我们这一个i的输出让内容 -->
            <a href="#" target="_blank" class="news-txt">【活动】{{@ "这是第" }}{{@  i   }}{{@ "个ul标签" }}</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">【活动】暑月蝉鸣礼包限量购 含大量祝福之石机会难得</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">【重要】公测版本更新内容及注意事项汇总</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">冒险岛2觉醒公测调研问卷-领奖通知</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">【活动】冒险家回归计划 欢迎回家!</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">【活动】邀请好友一起冒险!</a>
            <span class="news-time">08/07</span>
        </li>
        <li>
            <span class="news-icon "></span>
            <a href="#" target="_blank" class="news-txt">【活动】七夕岛上大冒险 鹊桥来相会</a>
            <span class="news-time">08/07</span>
        </li>
    </ul>
    <% } %>
</script>

<!-- 3.调用api来渲染模板页面 -->
<script>

    //引用模板
    var ul = template('tpl1',{ list : 6});

    document.getElementById('newBd').innerHTML = ul;

    //给每个模板顶部的导航点击事件
    $("#newsHd a").on('click',function(){

        //设置对应的颜色更改
        $(this).addClass('active').siblings('a').removeClass('active');
        //设置下方对应的span的移动
        $('.tab-arr-line').css('left',$(this).position().left + 'px');

        //让下方显示的盒子与我的导航栏一致
        var idx = $(this).index();
        $('.news-list').eq(idx).show().siblings('.news-list').hide();

    });

</script>

完整项目下载地址:
gitHub: https://github.com/Alex-Li2018/maoxiandaoProject

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Art-template是一款高性能、轻量级的模板引擎,适用于Node.js和浏览器环境。它以简洁明了的语法,支持模板继承、条件判断、循环遍历等常见功能,同时还提供了强大的过滤器和自定义标签功能。 Art-template的使用逻辑如下: 1. 安装Art-template 可以通过npm安装Art-template,命令如下: ```npm install art-template --save``` 2. 引入Art-template 在Node.js中,可以使用require语句引入Art-template: ```const template = require('art-template');``` 在浏览器中,可以使用script标签引入Art-template: ```<script src="path/to/art-template.js"></script>``` 3. 编写模板 Art-template使用{{}}包裹变量、表达式或语句。例如,以下是一个简单的模板: ``` <!DOCTYPE html> <html> <head> <title>{{title}}</title> </head> <body> <h1>{{title}}</h1> <p>{{content}}</p> </body> </html> ``` 4. 渲染模板 使用template方法可以将模板渲染成字符串。例如: ``` const template = require('art-template'); const data = { title: 'Art-template', content: 'A lightweight and powerful template engine' }; const html = template('path/to/template', data); console.log(html); ``` 在上面的例子中,我们将data对象传递给了模板,使用{{}}包裹的变量会被替换成data对象中的对应值,最终输出渲染后的HTML字符串。 5. 高级用法 除了基本的变量替换,Art-template还支持模板继承、条件判断、循环遍历等高级用法。例如,以下是一个使用if语句和each语句的模板: ``` {{if isAdmin}} <p>Welcome, admin</p> {{else}} <p>Welcome, user</p> {{/if}} <ul> {{each list}} <li>{{$index}}. {{$value}}</li> {{/each}} </ul> ``` 以上就是Art-template的使用逻辑,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值