Regular 中事件分为两类
- DOM事件
- 组件事件
在大部分情况下,它们的使用方式和表现一致。
DOM节点上 所有以
on-
开头的属性都会被当做DOM事件处理
Syntax : on-event={Expression}
每次event触发时,表达式 Expression
都会被运行一次
Example:
<button on-click={count = count + 1}> count+1 </button> <b>{count}</b>,
如果表达式执行后的值为false(===),事件的默认行为将会被阻止,当然你也可以通过$event.preventDefault()来阻止事件的默认行为。
比如on-tap
, on-hold
Usage
Component.event(event, fn)
Arguments
- event: 自定义事件名
- fn(elem, fire)
- elem: 被绑定节点
- fire: 触发事件函数
注意如果需要做 销毁工作 ,与指令一样,你需要在 fn 中返回一个函数用来做销毁工作
Example
定义 on-enter
事件处理回车逻辑
var dom = Regular.dom;
Regular.event('enter', function(elem, fire){
function update(ev){
if(ev.which == 13){ // ENTER key
ev.preventDefault();
fire(ev); // if key is enter , we fire the event;
}
}
dom.on(elem, "keypress", update);
});
<!-- use in template -->
<textarea on-enter={this.submit($event)}></textarea>
Tip: 模板中出现的 this
指向组件实例本身,回车后会运行实例的submit方法
查看 $event了解更多
注意:除非是自定义事件,其它事件无论浏览器是否支持,都会通过addEventListener进行绑定
on-*
会在当前节点绑定事件,在某些情况下(比如大列表),这种方式不是很高效。
在这种情况下,我们可以尝试使用 delegate-
代替 on-
,来避免潜在的性能问题,delegate-
只会绑定一次事件到 父节点 上
Example
<div delegate-click="remove">Delte</div> //Proxy way via delegate
<div delegate-click={this.remove()}>Delte</div> // Evaluated way via delagate
但是,需要注意的是,delegate-
并非是「银弹」
- 避免在高频触发的事件中使用( 比如
mouseover
),这样反而会产生性能问题 - 事件必须可冒泡
$event
会在每次事件触发时注入到 data.$event
中,你可以直接在模板里使用它。
Example
<script async src="//jsfiddle.net/leeluolee/1o2gf4um/embed/js,result/"></script>$event
对象是被修正过的,在兼容 IE6 的前提下,你可以使用以下规范内的属性
- origin: 绑定节点
- target: 触发节点
- preventDefault(): 阻止事件默认行为
- stopPropagation(): 阻止事件冒泡
- which
- pageX
- pageY
- wheelDelta
- event: 原始事件对象
对于自定义事件,$event 即传入 fire 触发器的对象
Regular 集成了一个轻量级的 Emitter,使得所有组件实例都可以使用以下接口来实现事件驱动的开发
- component.$on: 用于添加事件监听器
- component.$off: 用于解绑事件监听器
- component.$emit: 用于触发某个事件
Example
<script async src="//jsfiddle.net/leeluolee/h03acpfy/1/embed/js,result/"></script>与DOM事件绑定类似,声明式组件以 on-
开头的属性都会被视作事件绑定
假设已经注册了一个名为 Pager
的翻页器组件
<Pager on-nav={ this.refresh($event) } />
每当 Pager
组件通过 $emit
抛出nav
事件,对应的 this.refresh($event)
就会被调用,执行组件上的 refresh 方法
是的,整个过程和 DOM 事件并无二样。但其中的 $event
代表 $emit 传入的__第一个__参数
Regular 会在组件实例初始化过程的关键阶段抛出事件
$config
: 会在 compile 之前触发$init
: 会在 compile 之后触发,此时,dom 结构已经生成,你可以通过 this.$refs 来获取了$destroy
: 会在组件被 destroy 时触发
$
前缀是为了标识内建事件
组件和DOM事件具有共性
-
表达式(e.g.
on-click={this.remove()}
)如果传入的是表达式,该表达式会在事件触发时被运行一次。
Example
<div on-click={this.remove(index)}>Delte</div>
这是一种最标准的写法,大多数时候你只会用到它
-
非表达式(e.g.
on-click="remove"
)
简化写法,等价于 on-click={this.$emit('remove', $event)}
,事件会以同样的事件名和参数被再次抛出,相当于做了一次代理
Example
<script async src="//jsfiddle.net/leeluolee/5hmawdcr/embed/js,result/"></script>- 组件事件由
$emit
方法抛出,而 DOM 事件由浏览器抛出 - DOM 事件由于 DOM 本身的特点,是可以冒泡的,而组件事件没有冒泡的机制
$event
在组件事件中是 $emit 传入的第一个参数,而在 DOM 事件中是封装过的事件对象