$on
$on 是用来在监听(注册)自定义事件的。
使用方法:
vm.$on(event, callback)
参数:
- event {string | Array} (自定义事件的名称,可以使用数组的方式复数注册。数组方式必须在2.2.0+中才支持)
- callback {Function} (自定义事件触发后,所执行的方法、函数)
示例:
vm.$on('myEvent', function(data) {
console.log(data);
});
源码:
var hookRE = /^hook:/;
Vue.prototype.$on = function(evert, fn) {
var vm = this; // this 就是 Vue 实例
// 判断 event 是否是数组
if(Array.isArray(event)) { // 当 event 是数组的时候,对数组进行循环,分次将事件注册。
for(var i = 0, l = event.length; i < l; i++) {
vm.$on(event[i], fn);
}
} else {
// 当event不是数组的时候,判断event是否注册过。
// 1、注册过,直接将方法push进对应的数组中。
// 2、没有注册过先在vm._events里面注册一个对应的数组,然后再把方法push进数组中。
// 这里其实就意味着,一个自定义事件,其实可以对应着多个方法,方法的执行顺序,就是添加顺序。
(vm._events[event] || (vm._events[event] = [])).push(fn);
if(hookRE.test(event)) {
vm._hasHookEvent = true;
}
}
return vm;
}
$emit
$emit 是手动触发当前实例上的一个指定事件。
使用方法:
vm.$emit(eventName, [...args])
参数:
- eventName {string} (需要触发的事件名称)
- [...args] (传递的参数,多个参数用数组,单个参数就可以直接用参数本身的格式)
示例:
vm.$emit('myEvent', 'happy');
源码:
Vue.prototype.$emit = function(event) {
var vm = this;
{
// 这里是将eventName变换为小写,并做一些检查
var lowerCaseEvent = event.toLowerCase();
if(lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
tip(
"Event \"" + lowerCaseEvent + "\" is emitted in component " +
(formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +
"Note that HTML attributes are case-insensitive and you cannot use " +
"v-on to listen to camelCase events when using in-DOM templates. " +
"You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."
);
}
}
// 获取该事件下的方法、函数
var cbs = vm._events[event];
// 判断cbs是否有值,是否为真
if(cbs) { // 当cbs为真的时候。
// 判断cbs是否大于一,如果大于一就确保cbs是一个数组,如果不大于一,就直接返回cbs
cbs = cbs.length > 1 ? toArray(cbs) : cbs;
// 获取传入的参数,大体就是,把arguments转换成数组,并且获取它下标为1的值
var args = toArray(arguments, 1);
var info = "event handler for \"" + event + "\"";
// 遍历cbs
for(var i = 0, l = cbs.length; i < l; i++) {
// 通过invokeWithErrorHandling方法,来安全的执行cbs[i],大体就是try catch, 防止方法出现异常的时候不会中断程序的执行。
invokeWithErrorHandling(cbs[i], vm, args, vm, info);
}
}
// 这里当cbs为假的时候会直接return vm什么都不会操作
return vm;
}