Vue 3 大改了事件绑定机制,事件绑定变成了简略的属性传递,$on
、$off
也没了,Vue 对象齐全失去了 EventBus 的性能。尤大最初安利了一个第三方库,用个 EventBus 发个事件还要第三方库?这也太 low 了吧。
JavaScript 原本原生就提供了事件绑定机制,前端开发都用了无数遍了,就是 addEventListener。addEventListener 是类 EventTarget 的成员办法,咱们能够给一个按钮绑定 click
事件,实际上是因为按钮的原型类 HTMLButtonElement
继承自 EventTarget
原生的 EventBus
不同于大多数 DOM 原型类,EventTarget 能够间接 new
,然而仅在较新的浏览器中才反对。咱们也不须要用元素这种重量级的货色。从下面的截图能够看到,Node
就继承自 EventTarget
,所以所有 DOM 节点都有 addEventListener
,这里举荐一种足够轻量级的节点: 正文
对于浏览器渲染引擎来说,正文就是一段解释性的文字,没有任何作用,纯正给开发者看的。然而正文写在 HTML 脚本中,它依然是一个节点,有本人的原型类 Comment,并且继承自 Node
。
Comment
类能够间接 new
,也能够应用比拟老的然而兼容性更好的形式 document.createComment
,它强制要求一个参数,是正文的内容。你能够写一些描述性的信息,如果没什么可说的,间接用空字符串也能够。
const myEventBus = document.createComment('my-event-bus');
有了 EventBus 实例就能够触发事件了。触发事件应用 dispatchEvent。dispatchEvent
接管一个 Event
对象,然而通常的 Event
对象不能传递用户的自定义数据,这时能够用 CustomEvent,它的 detail
属性能够存储任意数据。
myEventBus.dispatchEvent(new CustomEvent('event-name', { detail: 'event-data'}));
须要留神的是,尽管 IE9+ 都反对 CustomEvent
,然而包含 IE11 在内都不反对 new CustomEvent
。尽管能够用 document.createEvent
然而操作简单,倡议用一下 Polyfill。
不过话说 Vue 3 都不想反对 IE 了咱们纠结那么多干嘛。。。
最初就能够接管事件了
myEventBus.addEventListener('event-name', ({ detail}) => {console.log(detail); // => event-data
});
新版浏览器中 addEventListener
还能够应用 {once: true}
实现单次绑定
对于调试
我的项目简单之后,绑定的事件会越来越多,开可能呈现绑定过后忘理解绑的 bug。我想看看我的 myEventBus
下面帮了哪些事件怎么看呢?
myEventBus 是一个 DOM 节点,所以它能够用浏览器的元素查看器调试
首先将其追加到 DOM 树上
document.appendChild(myEventBus)
这时就能够在 DOM 树的开端找到这个正文节点,能够间接查看
你还能找到绑定事件代码的地位,还能够间接删除某个事件绑定。是不是很不便?