为了账号安全,请及时绑定邮箱和手机立即绑定

如何捕获Web组件中的自定义事件?

如何捕获Web组件中的自定义事件?

叮当猫咪 2023-09-21 14:20:30
为了让 Web 组件相互通信,我使用了自定义事件。让我们想象一下以下情况:WebComponentA 使用或包含 WebComponentB,如果单击按钮,WebComponentB 会发送 CustomEvent(bubbles:true,composed:true)。如果 WebComponentB 发送此事件,WebComponentA 想要执行某些操作。我应该如何在 WebComponentB 中调度事件?window.dispatchEvent(customEvent);或者this.shadowRoot.dispatchEvent(customEvent);我应该如何捕获 WebComponentA 中的事件?window.addEventListener(custom-event, () => { );或者this.shadowRoot.addEventListener(custom-event, () => { );我应该考虑使用其中一种或另一种是否有任何负面影响?谢谢你!
查看完整描述

1 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

在组件本身上分派事件,bubble: true, composed: true以便该事件将冒泡到任何监视它的地方。当您想要非常具体地拥有大量可预测性和共享状态时,我的意思是这确实是所需的紧密耦合,那么只需在全局self(即window在浏览器中)。这里有一些随机的例子,我希望有所帮助,他们所做的只是为了展示一个例子而相对无用。总体想法是在有意义的情况下松散地耦合事物,事件只是传递与状态更改相关的消息。组件始终可以是相当隔离的,无论它在什么上下文中运行,都可以单独关注它对该信息的处理(准备和接收模型——这是功能模式高度适用的地方)。如果需要更多细节或令人困惑,请随时将其拼写出来,我们可以尽力提供帮助。

另请注意,因为我没有设置任何 ShadowRoot,所以组合标志在此示例中根本没有用处。

宽广地:

  • 全局:(其他上下文中的self同义词window或工人);这里协调旨在跨许多事物紧密耦合的事件——当需要非常具体的协调系统时,这是迄今为止最简单的组织方案;对于这种情况,只需在此处侦听并分派事件即可;connectedCallback在和中添加和删除事件侦听器disconnectedCallback。然后,不再需要通过冒泡或直接self.dispatchEvent('type', {detail:...})冒泡等方式调度。

  • 节点:在树的任何级别,当组件具有任何类型的任何状态或事件时,处理场景并创建适当的消息作为 和event.detail合理的名称作为event.type,然后从处理该逻辑的节点分派它。其他节点(父节点等)可以监视事件event.bubble,并且当从影子节点分派时,这些事件可以使用该composed:true标志来允许事件在影子根之外继续。或者该元素可以处理内部事件并分派适合该类型的新类型的事件和有效负载。

<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);

      }

  });


查看完整回答
反对 回复 2023-09-21
  • 1 回答
  • 0 关注
  • 92 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信