template7是framework7的内置模板引擎,在此之前使用过jquery-tmpl,不过刚刚打开github看了下,已经停止更新,并且将要被JsRender所替代。妹的,JsRender又是什么鬼啊?扯远了,之前听过别人关于jquery-tmpl模板引擎的技术分享,它的源码加上一堆注释才100多行。在此之前模板给我的概念是jsp那种,要与java后端一起配合使用的,后端用数据模型把值传到前台,前台再通过${}获取值。如果需要进行一些条件判断,则使用jstl。如果前台要异步局部刷新页面,则用ajax来实现,返回的数据以拼字符串的方式把DOM嵌入到原来的页面,但是拼字符串这种方式实在坑爹,不仅写来痛苦,维护起来也痛苦。后来就使用js动态添加HTML,然后再用js把数据填充进去。写法有以下两种:

  <script type="text/html" id="theTemplate">
<div class="dialog">
<div class="title">
<img src="close.gif" alt="点击可以关闭" />亲爱的提示条
</div>
<div class="content">
<img src="delete.jpg" alt="" /><span>您真的要GG吗?</span>
</div>
<div class="bottom">
<input id="Button2" type="button" value="确定" class="btn"/>&nbsp;&nbsp;
<input id="Button3" type="button" value="取消" class="btn"/>
</div>
</div>
</script> var template = document.getElementById("theTemplate").innerHTML ;

或:

<textarea id="theTemplate" style="display:none">
<div class="dialog">
<div class="title">
<img src="close.gif" alt="点击可以关闭" />亲爱的提示条
</div>
<div class="content">
<img src="delete.jpg" alt="" /><span>您真的要GG吗?</span>
</div>
<div class="bottom">
<input id="Button2" type="button" value="确定" class="btn"/>&nbsp;&nbsp;
<input id="Button3" type="button" value="取消" class="btn"/>
</div>
</div>
</textarea> var template = document.getElementById("theTemplate").value ;

这种写法优点是:

  1. 比拼字符串优雅很多

  2. 浏览器不会读取到就渲染,所以里面的img的src也不会自动获取

缺点:

  1. script标签里面不能直接写变量,又需要频繁的操作修改DOM。

可能是基于以上的缺点,引入了jquery-tmpl模板引擎,但我觉得前端模板的真正意义在于前后端分离,即无法通过controller把数据发送到view,只能以接口请求的形式得到数据,但是HTML本身又没有jstl或freemarker那样获取变量或者进行if判断、each循环的功能,所以,需要有一种工具来进行功能的替代,这时前端模板引擎纷纷出现,五花八门,像我们项目中有用到的underscore.js内置的模板引擎,但是那个功能比较单一,毕竟模板引擎只是他的一部分,功能够用就好。
而我们今天要说的template7,则是一个功能更为强大,更为全面的模板引擎,官方说它执行速度也很快,但是到底快不快,比哪些快,我没去研究,有兴趣的可以自己拿几种模板引擎对比下。

Template7还嵌入了handlebars的表达式{{#}}


<div class="list-block">
<ul>
{{#each items}}
<li class="item-content">
<div class="item-inner">
<div class="item-title">{{title}}</div>
</div>
</li>
{{/each}}
</ul>
</div>

其实个人不喜欢一个模板搞几种表达式,不过猜测作者应该是考虑到在多种情况下都可以使用,即{{}}可能在当前的上下文中有了其他的用法或者含义,如果我模板也请也使用这个就会产生冲突,至于能有什么用法,不要问我,我不知道,但我知道jquery-tmpl模板中有两种取变量值的写法,${}和{{=}},${}的写法是和freemarker、jsp等模板的取值方法是一样的,所以会产生混淆,所以一般用{{=}}。

模板中我们经常能见到的方法,这里就简单的一笔带过,相信看官网的介绍会更加明了。我们就主要说一下不常用的或者其他模板引擎里没有的一些功能。

Template7有以下表达式语法:

Variables

  • {{title}} - plain variable. Outputs "title" variable in current context

  • {{../title}} - plain variable. Outputs "title" variable in parent context

  • {{../../title}} - plain variable. Outputs "title" variable in parent context of parent context

  • {{this}} - plain variable. Outputs variable equals to current context

  • {{person.name}} - plain variable. Outputs variable equals to "name" property of "person" variable in current context

  • {{../person.name}} - plain variable. The same but for parent context

  • {{@index}} - access to additional data variable. Such data variables could be used in helpers

Block expressions

  • {{#each}} - begin of block expression

  • {{else}} - begin of block inverse expression (where supported)

  • {{/each}} - end of block expression

  • {{#each reverse="true"}} - begin of block expression with passed reverse:true hash arguments

Helpers
Helpers could be plain expressions and block expressions:

  • {{join myArray delimiter=", "}} - execute "join" helper and pass there "myArray" variable of current context and delimiter:', 'hash argument

以上比较少见的是{{../title}},{{this}},{{person.name}},{{@index}}这几种写法,那我们就举个栗子(非糖炒)说一下:

<script id="tmplOne" type="text/template7">
<p>Hello, my name is {{firstName}} {{lastName}}</p>
<ul>
{{#each arr}}
<li>{{sex}}======={{birthday}}======={{../firstName}}</li>
{{/each}}
</ul>
<p>----------------</p>
<ul>
{{#each arr reverse="true"}}
<li>{{sex}}======={{birthday}}</li>
{{/each}}
</ul>
</script> var context = {
firstName: 'John',
lastName: 'Doe',
arr: [
{
sex: 'boy',
birthday:'1991-1-1'
},
{
sex: 'girl',
birthday:'1991-2-2'
}
]
}; 输出如下:
Hello, my name is John Doe
boy=======1991-1-1=======John
girl=======1991-2-2=======John
----------------
girl=======1991-2-2
boy=======1991-1-1

到这里想必大家都已经看明白了吧,如果写成下面这样,

{{#each arr}}
<li>{{sex}}======={{birthday}}======={{firstName}}</li>
{{/each}}

{{firstName}}是无法取到值得,因为当前一级是arr里面,往上一级才能或取到值。

第二个:

<script id="tmplOne" type="text/template7">
<p>Here are the list of people i know:</p>
<ul>
{{#each people}}
<li>{{@index}}======== {{this.test}} ********{{this}}</li>
{{/each}}
</ul>
<p>{{person.name}}</p>
</script> var context = {
people: ['John Doe', {test:'test'}],
person: {
name: '虚空假面'
}
};
//输出结果:
Here are the list of people i know:
0======== ********John Doe
1======== test ********[object Object]
虚空假面

下面说一说内置的一些辅助方法:

{{join myArray delimiter=", "}}

这个也是很少见到,有什么用,怎么用?
官方是这么说的:This plain helper will join Array items to single string with passed delimiter

<p>Genres: {{join genres delimiter=", "}}</p>

{
genres: ['comedy', 'drama']
} 输出:
<p>Genres: comedy, drama</p>

这个方法有木有很像js中的join()方法,

<script type="text/javascript">
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr.join())
</script> 输出:
George,John,Thomas

其实两者的作用也是一样的,都是把数组对象转成字符串,并用指定符号隔开。

{{#each}}...{{else}}...{{/each}}

之前用过{{#if}}...{{else}}...{{/each}},但是见到{{#each}}...{{else}}...{{/each}}感觉一脸懵逼
看栗子吧:

<p>Car properties:</p>
<ul>
{{#each props}}
<li>{{@key}}: {{this}}</li>
{{else}}
<li>No properties</li>
{{/each}}
</ul>
<p>obj:</p>
<ul>
{{#each obj}}
<li>{{@key}}: {{this}}</li>
{{else}}
<li>No properties</li>
{{/each}}
</ul>
<p>exp:</p>
<ul>
{{#each exp}}
<li>{{@key}}: {{this}}</li>
{{else}}
<li>No properties</li>
{{/each}}
</ul>
var context = {
props: {
power: '150 hp',
speed: '200 km/h',
},
obj: {},
exp:false
}; 输出:
Car properties:
power: 150 hp
speed: 200 km/h obj:
No properties exp:
No properties

这下明白了吧,其实他就下面这种形式的缩写。

<ul>
{{#if obj}}
{{#each obj}}
<li>{{@key}}: {{this}}</li>
{{/each}}
{{else}}
<li>No properties</li>
{{/if}}
</ul>

{{#unless}}...{{else}}...{{/unless}}

这个跟if else相反,没什么好说的,感觉有些鸡肋,有了if else还造这玩意干啥?不懂

{{#with}}...{{/with}}

这个跟{{#each}}...{{/each}}差不多,也是个鸡肋,对比栗子如下:

    <p>with</p>
{{#with props}}
<p>Car has {{power}} power and {{speed}} maximum speed</p>
{{/with}} <p>each</p>
{{#each props}}
<p>Car has {{this}} {{@key}}</p>
{{/each}} var context = {
props: {
power: '150 hp',
speed: '200 km/h',
}
};
输出:
with
Car has 150 hp power and 200 km/h maximum speed each
Car has 150 hp power
Car has 200 km/h speed

{{#variableName}}...{{/variableName}}

If you pass a block expression with helper name that is in the
expression context, then it will work like {{#each}} helper for this
context if it is an Array, and will work like {{#with}} helper if it
is an Object:

以上是官方的解释,也就是根据传入数据的类型是对象还是数组自动的去执行。

<p>数组:</p>
<ul>
{{#people}}
<li>{{name}} - {{age}} years old</li>
{{/people}}
</ul>
<p>对象:</p>
{{#props}}
<p>Car has {{power}} power and {{speed}} maximum speed</p>
{{/props}}
<p>其他</p>
{{#title}}
<p>{{this}}</p>
{{/title}} people: [
{
name: 'John Doe',
age: 18
},
{
name: 'Mark Johnson',
age: 21
}
],
props: {
power: '150 hp',
speed: '200 km/h'
},
title: 'Friends' 输出:
数组:
John Doe - 18 years old
Mark Johnson - 21 years old 对象:
Car has 150 hp power and 200 km/h maximum speed 其他
Friends

这个方法看起来挺好用,但是我觉得会导致程序读起来不明确,出了错也不容易排查,还是觉得鸡肋。

{{escape}}

This plain helper returns escaped HTML string. It escapes only the following characters: < > " &

这个方法用来把几个特定的字符< > " &转码成HTML字符串,目前我还没想到在什么场景下需要转码。

<h1>{{title}}</h1>
<p>{{escape body}}</p> {
title: 'Paragraphs',
body: 'We need to use <p> tags to add paragraphs in HTML',
} <h1>Paragraphs</h1>
<p>We need to use &lt;p&gt; tags to add paragraphs in HTML</p>

{{js "expression"}}

js表达式,我觉得这个方法还是比较有用的,之前曾遇到一个问题,通过API后台传过来一堆内容,然后我把它全部填到模板里,但是,这些数据里有些内容,比如文件大小,传过来是字节的,我需要根据大小转成KB,MB,GB等单位,这一步还好,但是计算出来往往小数点后好多位,比如3.222222MB,模板当时用的jquery的,当时就懵逼了,只能去找后端。但是如果模板能够用js表达式的话,这个问题就能解决了。

<h3>{{title}}</h3>
<p>Price: ${{js "this.price * 1.2"}} </p>
<p>{{js "this.inStock ? 'In Stock' : 'Not in stock'"}} </p>
<p>{{js "this.number.toFixed(2)"}}</p> title: 'iPhone 6 Plus',
price: 1000,
inStock: true,
number:2.22222 输出:
iPhone 6 Plus
Price: $1200
In Stock
2.22

{{#js_compare "expression"}}...{{/js_compare}}

在我看来还不如if else用的顺手,鸡肋

<h3>{{title}}</h3>
<p>Price: ${{price}} </p>
<p>{{#js_compare "this.color === 'white' && this.memory > 16"}}Not in stock{{else}}In stock{{/js_compare}} </p>
<p>
{{#if "this.color === 'white' && this.memory > 16"}}
Not in stock
{{else}}
In stock
{{/if}}
</p> title: 'iPhone 6 Plus',
price: 1000,
color: 'white',
memory: 32 iPhone 6 Plus
Price: $1000
Not in stock
Not in stock

此外,template7还支持添加、删除自定义helpers,即根据需要扩展自己需要的方法,感觉也没啥卵用

Template7.registerHelper(name, helper)

Template7.unregisterHelper(name)

name - string - helper name
helper - function - helper function to handle passed context

还有几个不常用的方法,就不在说了,有兴趣自己去官网看一下。
总的来说,感觉template7里面重复的东西太多,之前有看过jquery-tmpl的源码才不到100行,underscore.js内置的模板好像70行以内。而它500行左右,搞了一堆七七八八的内容,但真正平常用到的只是少部分,如果让我用的话,我可能会去掉里面的一些内容再用,或者直接选用更加精简的模板引擎。
暂时先写到这里,有时间,再补充一点对源码的认识。

template7入门教程及对它的一些看法的更多相关文章

  1. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  2. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  3. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  4. Content Security Policy 入门教程

    阮一峰文章:Content Security Policy 入门教程

  5. gulp详细入门教程

    本文链接:http://www.ydcss.com/archives/18 gulp详细入门教程 简介: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优 ...

  6. UE4新手引导入门教程

    请大家去这个地址下载:file:///D:/UE4%20Doc/虚幻4新手引导入门教程.pdf

  7. ABP(现代ASP.NET样板开发框架)系列之2、ABP入门教程

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之2.ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  8. webpack入门教程之初识loader(二)

    上一节我们学习了webpack的安装和编译,这一节我们来一起学习webpack的加载器和配置文件. 要想让网页看起来绚丽多彩,那么css就是必不可少的一份子.如果想要在应用中增加一个css文件,那么w ...

  9. 转载:TypeScript 简介与《TypeScript 中文入门教程》

    简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构 ...

随机推荐

  1. .Net Core中无处不在的Async/Await是如何提升性能的?

    一.简介 Async/Await在.Net Core中真的是无处不在,到处都是异步操作,那为什么要用?有什么作用?别人说能提升性能?网上一堆文章看的绕晕了也没说清楚, 所以这里从理论,实践,原理一个个 ...

  2. CDN网络科普小文(小说版)

    引言 作为公司 cdn 小组的一名小码仔,我为写一篇 cdn 的科普文章准备了好一段时间(大概有一个多月没有更新我的社交账号了). 在我刚进入公司,培训完,进入小组,了解到我们做的是 cdn 相关的工 ...

  3. BBS 项目(四)

    目录 BBS 项目(四) 首页布局 个人头像显示 个人站点路由设计 个人站点页面设计 base.html site.html 左侧过滤功能 404.html BBS 项目(四) 首页布局 <!D ...

  4. *****又错一道,不知道为啥。。。 ybt【例5.19】字符串判等

    [题目描述] 判断两个由大小写字母和空格组成的字符串在忽略大小写,且忽略空格后是否相等. [输入] 两行,每行包含一个字符串. [输出] 若两个字符串相等,输出YES,否则输出NO. 代码我觉得没啥问 ...

  5. new和@Autowired的区别

    controller层: @RequestMapping("/payment") @RestController public class WxPayController { pu ...

  6. Failed to execute "C:\learn\C\程序练习\1.exe": Error 0: 操作成功完成。 请按任意键继续. . .问题解决

    在DEV中编译运行时出现以上提示,原因是该文件被杀毒软件隔离了,认为它是病毒文件 解决办法,找到该文件进行恢复

  7. web服务器-Nginx下载限速

    web服务器-Nginx下载限速 一. 限速介绍 在生产环境中,为了保护WEB服务器的安全,我们都会对用户的访问做出一些限制,保证服务器的安全及资源的合理分配. 限流(rate limiting)是N ...

  8. java的https的get请求

    package com.wl.webservice; import java.io.InputStream; import java.net.HttpURLConnection; import jav ...

  9. AOP详解之三-创建AOP代理后记,创建AOP代理

    AOP详解之三-创建AOP代理后记,创建AOP代理. 上篇文章已经获取到了AOP的信息,接下来就是拿着这些AOP的信息去创建代理了. 首先我们看下创建AOP代理的入口处. //这个方法将返回代理类 p ...

  10. 如何使用docker制作开发集成环境

    1. 编写最基本的Dockerfile 内容:touch 一个Dockerfile FROM ubuntu 2. 创建基本的docker镜像 docker build  -t ubuntu:v1 . ...