触发事件
trigger
方法
组件触发事件的函数为trigger(eventName, [...args])
eventName
触发事件名args
传给事件处理函数的参数
上例中,可以看到触发一个increase
事件的方法为:this.trigger('increase')
。
通过它我们还可以为事件处理函数传递数据。
<li ev-click={self.likeThisBook}>{self.get('book')}</li>
var Book = Intact.extend({
template: template,
likeThisBook: function() {
// 将book传给事件处理函数
this.trigger('like', this.get('book'));
}
});
var Book = self.Book;
<ul>
<Book
ev-like={self.like}
v-for={self.get('books')}
book={value}
/>
你喜欢的书是:{self.get('book')}
</ul>
var App = Intact.extend({
template: template,
defaults: function() {
this.Book = Book;
return {
books: ['Javascript程序设计', '未来简史', '红楼梦']
}
},
like: function(book) {
this.set('book', book);
}
});
Intact.mount(App, document.getElementById('apptrigger'));
组件默认事件
$change事件
在Intact实例#$change事件章节,我们介绍过,组件每一次set()
触发数据变更,
都会触发相应的事件。所以我们可以监听子组件某个属性的变更,而无需子组件
显式地抛出事件。
<button ev-click={self.add}>+1</button>
var Component = Intact.extend({
template: template,
defaults: function() {
return {count: 0}
},
add: function() {
this.set('count', this.get('count') + 1)
}
});
var Component = self.Component;
<div>
<Component ev-$change:count={self.setCount} />
子组件被点击了{self.get('count') || 0}次
</div>
var App = Intact.extend({
template: template,
_init: function() {
this.Component = Component;
},
setCount: function(c, count) {
this.set('count', count);
}
});
Intact.mount(App, document.getElementById('apptrigger1'));
可以看到Component
组件并没有显式地抛出事件,但只要count
变更,就会触发$change:count
事件。
监听
$change:count
设置数据,还是有点麻烦,后面将介绍如何通过v-model
简化操作
$receive事件
@since v2.2.0
从v2.2.0开始,组件还提供了一个$receive
事件,它会在组件接收到父组件传给子组件的变更后的新属性
时触发。与$change
事件不同的是,$change
事件只要属性变更就会,不管属性的来源是父组件传递新属性
值导致,还是内部自己改变的。通过receive
事件,我们可以很方便地修正父组件传给自己的属性值。
例如:下例中,我们将父组件传递的字符串转为数字
<div>
<button ev-click={self.add}>+1</button>
value: {self.get('value')} type: {typeof self.get('value')}
</div>
var Component = Intact.extend({
template: template,
defaults: function() {
return {value: 0}
},
_init: function() {
// 初始化时,也修正
this._fixValue();
// 接收到新值时,修正
this.on('$receive:value', this._fixValue);
},
_fixValue: function() {
// 如果你打开调试工具,可以看到log信息打印的时机
// 内部改变,或者数据没有变更时不会执行
console.log('fix value');
var value = this.get('value');
this.set('value', Number(value));
},
add: function() {
this.set('value', this.get('value') + 1)
}
});
var Component = self.Component;
<div>
<Component v-model="count" />
<button ev-click={self._set}>点击这里,将count设为"10"</button>
</div>
var App = Intact.extend({
template: template,
defaults: function() {
this.Component = Component;
return {count: '100'};
},
_set: function() {
this.set('count', 10);
}
});
Intact.mount(App, document.getElementById('receive'));
$receive
事件只有在更新子组件传递新的属性值时触发,而不会在初始化时触发
组件生命周期事件
组件的默认事件除了$change
类,还有一组跟生命周期相关的事件。详见组件生命周期
on
方法
利用实例提供的on(eventName, callback)
方法,我们可以给实例对象绑定事件。结合前面提到的默认事件,
我们可以实现类似watch
的功能。
eventName
监听的事件名callback
事件回调函数,默认this
指向触发该事件的实例
<div>
<button ev-click={self.add}>被点击了{self.get('count')}次</button>
当点击5次时,会弹出alert
</div>
var App = Intact.extend({
template: template,
defaults: function() {
return {count: 0}
},
_init: function() {
// 监听count变更,等于5次时,弹出alert
this.on('$change:count', function(c, count) {
if (count === 5) {
console.log('$change:count', $('#apptrigger2').find('button').text())
alert('你点击了5次!');
}
});
// 为了测试$change:count和$changed:count的区别
this.on('$changed:count', function(c, count) {
if (count === 5) {
console.log('$changed:count', $('#apptrigger2').find('button').text())
}
});
},
add: function() {
this.set('count', this.get('count') + 1);
}
});
Intact.mount(App, document.getElementById('apptrigger2'));
上例中,如果你打开控制台,你可能会发现:
$change:count
查询到button
的文案为:”被点击了4次“; 而$changed:count
查询到的文案为:”被点击了5次“(alert会阻塞渲染,所以界面看不到差别)。这正是$change
与$changed
事件的差别,前者发生在更新前,后者发生在更新后。