$ on emit off
定义(是什么)
- $on 订阅消息 (监听实例上的某个具体事件)
- $once 只订阅一次(尤其适用场景)
- $emit 发布消息(触发实例上的某个具体事件)
- $off 取消订阅消息
- xxx
场景
-
v-on 与 $emit 父子组件中的 事件传递
父组件中 v-on:myEvent="handleEvent" // 监听子组件中的 myEvent消息 子组件中 this.$emit("myEvent",args) -
$on 对第三方组件 内部事件的拦截优点:不对原来的组件做任何修改
// eg 对elementUI等三方组件的内部方法改造与拦截 this.$refs['form'].$on("change",()=>{}) -
on 与 emit 配合公共组件使用,也就是 eventBus,那么就能实现 全局的消息发送,贯穿全局
this.eventBus.on("myEvent",()=>{}) this.eventBus.emit("myEvent","msg") -
on 与 emit 配合使用,自己封装组件的定义 自定义事件
.... -
xxx
设计模式:订阅者与发布者模式
经过研究源码解读,实现原理其实就是 订阅者与发布者模式
-
源码如下
-
on的源码
function eventsMixin (Vue) { var hookRE = /^hook:/; Vue.prototype.$on = function (event, fn) { var vm = this; if (Array.isArray(event)) { for (var i = 0, l = event.length; i < l; i++) { vm.$on(event[i], fn); } } else { (vm._events[event] || (vm._events[event] = [])).push(fn); // optimize hook:event cost by using a boolean flag marked at registration // instead of a hash lookup if (hookRE.test(event)) { vm._hasHookEvent = true; } } return vm }; -
emit的源码
Vue.prototype.$emit = function (event) { var vm = this; { 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]; if (cbs) { cbs = cbs.length > 1 ? toArray(cbs) : cbs; var args = toArray(arguments, 1); var info = "event handler for \"" + event + "\""; for (var i = 0, l = cbs.length; i < l; i++) { invokeWithErrorHandling(cbs[i], vm, args, vm, info); } } return vm }; }
-
-
代码学习(学习源码过程中,发现有几点写的很好,记录如下)
-
字典或则对象 中的属性判空并初始化
(vm._events[event] || (vm._events[event] = [])).push(fn); -
try catch的封装// fn 函数 ctx,this 对象,args 参数 function invokeWithErrorHandling(fn,ctx,args){ var res try{ res = args ? fn.apply(ctx,args) : fn.call(args); }.catch(e){ handleError(e) // js 内部函数 } return res }
-
-
ing...