javascript - 如何在 Web 组件中捕获自定义事件?
问题描述
为了让 Web 组件相互通信,我使用了自定义事件。让我们想象一下:
WebComponentA 使用或包含 WebComponentB,如果单击按钮,WebComponentB 会发送一个 CustomEvent(气泡:true,composition:true)。如果 WebComponentB 发送此事件,WebComponentA 想要做某事。
我应该如何在 WebComponentB 中调度事件?
window.dispatchEvent(customEvent);
或者
this.shadowRoot.dispatchEvent(customEvent);
我应该如何在 WebComponentA 中捕获事件?
window.addEventListener(custom-event, () => {
);
或者
this.shadowRoot.addEventListener(custom-event, () => {
);
我应该考虑使用一种或另一种的负面影响吗?
谢谢!
解决方案
在组件本身上调度事件,bubble: true, composed: true
这样事件就会冒泡到任何关注它的东西。当您想要非常明确地拥有大量可预测性和共享状态时,我的意思是这确实是一种紧密耦合,那么只需在全局上编排事件self
(即window
在浏览器中)。这里有一些随机的例子,我希望有所帮助,他们所做的只是为了展示一个例子而相对无用。整体的想法是在有意义的情况下松散耦合事物,事件只是传递与状态变化相关的消息。组件总是可以相当隔离,并且无论它在什么上下文中运行,都可以单独关注它对该信息的作用(准备和接收模型——这是功能模式高度适用的地方)。如果需要更多细节或感到困惑,请随时将其拼写出来,我们可以尝试提供帮助。
还要注意,因为我没有设置任何 shadowRoot,所以组合标志在此示例中根本没有用。
宽广地:
全局:(其他上下文中的
self
同义词window
或工作人员);此处的协调事件旨在与许多事物紧密耦合——当需要非常具体的协调系统时,这是迄今为止最简单的组织方案;对于这种情况,只需在此处侦听和调度事件;在 and 中添加和删除事件侦听connectedCallback
器disconnectedCallback
。self.dispatchEvent('type', {detail:...})
然后不再需要在任何地方发送冒泡或直接冒泡等。节点:在树的任何级别,当组件具有任何状态或任何类型的事件时,处理场景并创建一个适当的消息作为
event.detail
和一个合理的名称作为event.type
,然后从处理该逻辑的节点调度它。其他节点——在自己的父节点等上——可以监视event.bubble
,当从影子节点调度时,这些事件可以使用composed:true
标志来允许在 shadowRoot 之外继续事件。或者该元素可以处理内部事件并分派适合该类型的新型事件和有效负载。<my-global>my global </my-global> <my-aye> aye (parent) <my-bee> bee (child) </my-bee> </my-aye> <my-bee> bee </my-bee> function eventdetails(event){ const {type, detail} = event; console.log({type, detail, self:this, path: event.composedPath(), event}); } customElements.define('my-global', class MyGlobalWatch extends HTMLElement{ constructor(){ super(); this.global = this.global.bind(this); } global(event){ eventdetails.call(this, event); } connectedCallback(){ self.addEventListener('global', this.global); } disconnectedCallback(){ self.removeEventListener('global', this.global); } }); customElements.define('my-aye', class MyAye extends HTMLElement{ constructor(){ super(); this.addEventListener('hi-aye', this.handle); this.addEventListener('hi-bee', this.handle); } handle(event){ eventdetails.call(this, event); if(event.type === 'hi-bee'){ self.dispatchEvent(new CustomEvent('global', {detail: event.detail, cancelable: true, composed: true, bubbles: false})); } } }); customElements.define('my-bee', class MyBee extends HTMLElement{ constructor(){ super(); this.addEventListener('hi-aye', this.handle); this.addEventListener('hi-bee', this.handle); this.ticker = this.ticker.bind(this); } handle(event){ eventdetails.call(this, event); } ticker(){ // 3 events of the same type, different configuration this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed +bubbles'}, cancelable: true, composed: false, bubbles: true})); this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> +composed +bubbles'}, cancelable: true, composed: true, bubbles: true})); this.dispatchEvent(new CustomEvent('hi-aye', {detail: {payload:'> -composed -bubbles'}, cancelable: true, composed: false, bubbles: false})); this.dispatchEvent(new CustomEvent('hi-bee', {detail: {stuff:'things'}, cancelable: true, composed: true, bubbles: true})); this._timer = setTimeout(this.ticker, 1234); } connectedCallback(){ this.ticker(); } disconnectedCallback(){ clearTimeout(this._timer); } });
推荐阅读
- python - 无法在 GitLab CI 的 docker/compose 映像中使用 DynamoDB docker 映像
- c# - C# 是否有办法将具有 int 字段(字节、ushort、ulong 等)的对象编写为字节数组?
- groovy - 在 Groovy 中重建地图
- java - 在链接列表中的特定位置插入节点,附加元素时抛出运行时错误
- javascript - Postman 获取url请求参数的值做一个测试
- c++ - 模板化派生类隐藏基类成员?
- javascript - 无法找出这个错误:Can't perform a React state update on an unmounted component
- c# - Dns.GetHostEntry 为远程 IP 地址返回本地 IP 地址
- stm32 - HAL_SPI_Transmit() 会丢弃接收到的数据吗?
- oracle - 我收到错误下标超出限制。我如何解决它?