shadow-template v0.0.2
shadow
shadow是一个支持组件化的javascript模板引擎,它可以让开发者使用自定义标签的方式来重用组件。
特性
shadow的语法借鉴一个非常快速和简洁的模板引擎 artTemplate。它只有几个必要的语句,学习成本非常低,运行效率却非常高,而且编译好的模板很方便调试。
基本使用
模板指令包含在{{ }}
内
输出
{{name}}
默认情况下,会对结果进行html转义输出,如果需要原样输出,需要在前面加个等号:
{{=name}}
关于输出有以下规则
- 基本类型将会直接输出
- 如果是对象类型,则调用其toString()方法输出
- 如果是function,则会先执行function,然后输出运行结果
- 如果是对象类型,且包含属性safeString = true,则不转义输出
判断
{{if offers.length === 0}}
<div>empty</div>
{{/if}}
可以有else
或else if
{{if offers.length > 0}}
<ul class="offers">
...
</ul>
{{else}}
<div class="no-results">no results</div>
{{/if}}
说明: if 语句后面的判断可以是任何有效的js表达式,非常灵活
循环
{{each offers as offer}}
<li>
{{offer.name}}
</li>
{{/each}}
可以在模板中使用当前的循环序号
{{each offers as offer index}}
<li>{{index}}. {{offer.name}}</li>
{{/each}}
可以对对象类型进行迭代
{{each props as value name}}
<dt>{{name}}{{name}}
<dd>{{value}}</dd>
{{/each}}
表达式
模板中不应该有业务逻辑,但有时候为了简化对象的引用需要使用一些赋值语句
{{! props = model.offer.props }}
{{ props.name }}
{{ props.age }}
...
熟悉了以上语法就可以编写模板代码了,但shadow的特点是允许以自定义标签的方式定义和使用组件,下面文档描述了如何定义和使用组件。
组件
带中划线的标签或首字母为大写的标签都会被引擎识别为组件
<x-panel>
<heading>{{title}}</heading>
<body>{{desc}}</body>
</x-panel>
或
<Button text="confirm" />
组件的定义
可以这样定义bootstrap中的button
<shadow-component name="x-button">
<button class="button button-{{type}}">{{children}}</button>
</shadow-component>
组件中可以使用调用组件的属性以及上下文中的变量,可以类比于函数调用的参数和closure上下文中的变量。
可以通过children
变量访问子节点,可以通过children.length
来判断是否有子节点
可以使用{{children}}
输出所有children的内容,如果要传递参数,可以使用{{children({...})}}
上述按扭组件可以这样使用:
<x-button type="default">confirm</x-button>
以上调用会输出:
<button class="button button-default">confirm</button>
下面是一个定义bootstrap panel的例子
<shadow-component name="x-panel">
<div class="panel {{type}}">
{{if children.heading || children.title}}
<div class="panel-heading">
{{children.heading}}
{{if children.title}}
<div class="panel-title">{{children.title}}</div>
{{/if}}
</div>
{{/if}}
{{if children.body}}
<div class="panel-body">
{{children.body}}
</div>
{{/if}}
{{if children.footer}}
<div class="panel-footer">
{{children.footer}}
</div>
{{/if}}
</div>
</shadow-component>
使用{{if children.title}}
来判断是否有title节点,使用{{children.title}}
来输出title节点,如果需要传递参数,则使用函数调用语句{{children.title({ item: item })}}
组件的使用
可以这样使用上述定义的panel
<x-panel type="primary">
<title>Panel Title</title>
<body>Panel Content</body>
</x-panel>
上述会输出
<div class="panel primary">
<div class="panel-heading">
<div class="panel-title">Panel Title</div>
</div>
<div class="panel-body">
Panel Content
</div>
</div>
变量作用域
假设有list
组件如下
<shadow-component name="x-list">
<ul>
{{each items as item}}
<li>{{ children({ item: item }) }}</li>
{{/each}}
</ul>
</shadow-component>
使用时
<div>
<x-list items={{offers}}>
<x-panel>
<title>{{item.title}}</title>
<body>
<dl>
<dt>price</dt>
<dd>{{item.price}}</dd>
</dl>
</body>
</x-panel>
</x-list>
</div>
上述x-panel中的item
对象使用的是组件中传递的item
参数,如果外围变量中也有item
变量,外围变量将会被隐藏。
这类似于函数参数变量和closure上下文中相同名称的变量,如果需要使用,则在组件调用前先保存成其他名称。
<div>
{{! thisitem = item }}
<x-list items="{{offers}}">
<title>{{item.title}}</title>
<body>
{{thisitem.title}}
</body>
</x-list>
</div>
9 years ago