微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以使用目标对象分派苗条的自定义事件?

如何解决是否可以使用目标对象分派苗条的自定义事件?

是否可以使用像原生浏览器事件这样的目标对象来分派一个 svelte 事件(使用 createEventdispatcher 创建)?

即在处理程序端接收 event.target.value 而不是 event.detail。

解决方法

是的,这是可能的,但涉及一些黑客攻击。

您可以查看 svelte 源代码以了解事件调度的工作原理。我将概述以下关键部分。

假设我们有两个组件,InnerOuter

<!-- Inner.svelte -->
<script>
import { createEventDispatcher } from 'svelte'
const dispatch = createEventDispatcher()
const dispatchFoo = () => dispatch('foo','bar')
</script>

<button on:click={dispatchFoo}>send</button>

<!-- Outer.svelte -->
<script>
import Inner from './Inner.svelte'
const handleFoo = (e) => { console.log('receive foo',e) }
</script>

<Inner on:foo={handleFoo}></Inner>

仔细想想,事件处理程序 handleFoo 是在 Outer 中创建的,但它实际上是在 Inner 上注册的。

检查你将看到的编译后的 JS 代码:

  1. inner.$$.callbacks["foo"] 持有事件处理程序 [src]
  2. 当您单击按钮并调用 dispatch 时,它只会读取潜在处理程序的 inner.$$.callbacks["foo"],如果找到,则使用 CustomEvent 作为参数调用它们 [src]

设置 customEvent.target 的唯一方法是使用 element.dispatchEvent(customEvent) 调度该自定义事件。但是 element.dispatchEvent 并没有贯穿整个过程。

解决方案(黑客)

编写您自己的createEventDispatcher

import { get_current_component } from 'svelte/internal'

function createEventDispatcher() {
  const component = get_current_component();
  return (type,target,detail) => {
    const callbacks = component.$$.callbacks[type];
    if (callbacks) {
      const event = new CustomEvent(type,{ detail });
      // the key is to call `dispatchEvent` manually to set `event.target`
      target.dispatchEvent(event);
      callbacks.slice().forEach((fn) => {
        fn.call(component,event);
      });
    }
  };
}

Svelte REPL

,

根据 hackape 的回答修改

import { get_current_component } from 'svelte/internal'

function createEventDispatcher() {
  const component = get_current_component(bubbles = true);
  return (type,{ bubbles,detail });
      // the key is to call `dispatchEvent` manually to set `event.target`
      target.dispatchEvent(event);
      /* You have already raised an event,you should not repeat the callbacks to avoid duplication
        callbacks.slice().forEach((fn) => {
          fn.call(component,event);
        });
      */
    }
  };
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。