模板语法
Buz.js使用基于HTML的模板语法,所有模板都是合法的HTML,所以能被尊村规范的浏览器和HTML解析器解析。
在底层我们会将模板变异成虚拟DOM渲染函数。结合Object.defineProperty进行双向相应, Buz能够智能的计算最少重新渲染的节点,并且当DOM移除时会做相应的接触监听依赖。
前提:模板渲染时会依赖视图组件数据
插值 文本
使用双大括号”Mustache”语法的文本插值
1
<p>{{msg}}</p>
Mustache 变迁将会替代为对应数据对象的msg属性值。当msg值发生改变时, 视图中依赖此属性的节点都会进行实时渲染。
插入HTML
使用三个大括号实现HTML节点渲染
1
{{{htmlcard}}}
使用三个大括号时也会实现文本插值,他与双大括号的唯一区别是一个是设置节点的textContent ,一个是使用插入新的DOM节点。
直接将视图组件的值作为HTML进行渲染时非常危险的,因为它很容易导致XSS攻击。 请只对可信内容使用插入HTML操作,绝不要对用户写入的数据进行渲染。
Attributes(特性)
Attributes中我们提供了三种使用方式:设置属性、指令、事件, 指令、事件调用方式我们将在下一节详细介绍。
采用冒号方式:即可事件属性的动态渲染。
1
<p :rel=”external nofollow” href=”hrefData” :class=”className” :customattr=”demo”></p>
若hrefData=”http:www.braveos.com”;className=”show”;不设置demo值,则渲染后的结果:
1
<p rel=”external nofollow” href=”http:www.braveos.com” class=”show” customattr=”demo”></p>
在模板渲染时,模板引擎会第一时间对每个标记进行解析,因此一定不要在表达式中出现alert等语法, 因为在模板尝试解析时会执行表达式,会对表达式内的语法进行执行。
指令
指令(Directives)是采用Attribute来进行引导的,使用b-前缀来调用指令, 我们提供了常用的几个指令,当然你可以自定义局部指令、全局指令来实现特定需求。
class
class指令用于动态编译class,我们通过下面的例子了解下class指令的用途
1
2
<p b-class=”true?’class1′:’class2′”></p>
<p class=”baseClass” b-class=”true?’class1′:’class2′”></p>
编译后的结果:
1
2
<p class=”class1″></p>
<p class=”baseClass class1″></p>
通过上面这个例子我们可以看出,class指令和:class的用途是一样的, 但是他的主要用途是可以和class进行混用,将公共样式在class中设置,并通过class指令设置动态class值。
show/hide(显示/隐藏)
此指令依赖BUI框架中的base.css,通过表达式返回的bool值设置hide样式或移除hide样式。
1
2
3
4
<p b-show=”true”>1</p>
<p b-show=”false”>2</p>
<p b-hide=”true”>3</p>
<p b-hide=”false”>4</p>
输出结果为(1、4):
1
2
3
4
<p>1</p>
<p class=”hide”>2</p>
<p class=”hide”>3</p>
<p>4</p>
高级用法
1
<p class=”hide” b-show=”true”>1</p>
渲染完毕后
1
<p class=””>1</p>
在某些特殊场景下,可能需要通过异步请求服务器,通过服务器参数来作为展示/隐藏依据, 为了防止在请求结束之前显示该标签,可以先设置为hide,然后通过show/hide指令实时监听异步返回结果, 服务器返回结果后再做业务处理。可以防止闪烁。
if/else-if/else(条件)
条件指令依赖于标签进行展示和隐藏,它与show/hide唯一区别在于,条件指令在DOM树不展示节点 ,而show/hide则是对标签进行show、hide操作。
1.条件表达式在运行时会把结果强制转换为BOOL值进行判断。
2.在配合else-if/else一起使用时,注意:指令必须在是同级标签。
1
2
<p b-if=”false”>测试节点</p>
<p b-if=”true”>测试节点1</p>
渲染完毕后
1
<p>测试节点1</p>
for(列表)
for循环指令,支持数组、对象、字符串、数字的循环渲染,并可以配合if指令进行筛选渲染
for循环指令支持多种调用方式(全量参数分别代表-【value、key、index】):
1
2
3
4
<p b-for=”value in 5″>测试节点{{value}}</p>
<p b-for=”value,key,index) in demoObj”>
key:{{key}};value:{{value}};index:{{index}}
</p>
当for循环指令配合if指令一起使用时,for渲染的权重高于if指令
1
<p b-for=”value in 5″ b-if=”value<2″>测试节点{{value}}</p>
输出的结果为:
1
2
<p>测试节点0</p>
<p>测试节点1</p>
事件
通过事件指令,可以完成对节点的事件注册或者切换,调用方式为:on:事件名称=”执行事件”
1
<button on:click=”function1″ type=”button”>按钮</button>
高级用法
经过上面的简单介绍后,相信大家已经对模板引擎的用法有了基本的用法,接下来我们来介绍下模板引擎的高级用法。
对于刚刚接触BUI框架的童鞋,建议跳过本节内容,对整体架构有了初步认识后,再来阅读本节内容可能会更容易理解。
Javascript表达式
在上面讲到的示例中我们都是采用简单的绑定一个属性值,但实际上,我们支持多属性绑定,也可以支持复杂的运算, Bui.js提供Javascript表达式,支持自定义的渲染逻辑。
1
2
3
4
5
{{ 1+1 }}
{{ true?”1″:”0″ }}
{{ “Bui.js”.split”).join’-‘) }}
<p :customattribute=”1+1″ :id=”‘id’+Date.now)”></p>
Javascript表达式处理逻辑:
1.尝试带入viewData运行表达式,并返回结果。
2.若运行时错误,则按照原表达式作为返回值进行返回。
计算属性/视图方法
计算属性是通过直接调用视图中的某个方法来实现视图渲染或事件绑定,最常见的是Event事件。
1
<button type=”button” on:click=”viewFunction”></button>
例如上面这个例子,通过上一小节表达式的说明,首先会尝试运行表达式,由于视图模型中未定义 viewFunction所以会直接抛出异常,表达式运行错误,然后直接将viewFuntion字符串作为返回值进行绑定。 在事件指令中,会尝试在view视图中寻找viewFunction方法,找到方法后进行事件注册。
除了事件指令会尝试将返回值作为视图方法进行查询外,还有text指令也支持此操作。接下来看下面的例子:
1
{{demo1+demo2}}
上面的例子可以看出是一个简单的加法运算,当存在复杂的计算,并且表达式中存在多个需要监听的视图模型数据时,在页面中 书写大量的JS语法会让人很头疼,这时我们可以通过计算属性来代替这个复杂的写法。
1
2
3
4
5
6
7
8
9
10
/**视图组件*/
…{
data:{
demo1:1,
demo2:2
},
function1:funtion){
return this.demo1+this.demo2;
}
}
1
{{function1}}
这种写法和直接在HTML使用表达式运行的结果是一样的,并且都可以实现属性的监听绑定。
指令权重
指令权重是指指令在运行前会按照权重进行一次排序,权重越高的指令执行越早,目前自定义权重的指令有:
for权重200 ; if权重100,其余指令默认权重为0
https://github.com/ZhangChuanHui/BUZ