是否可以像本地浏览器事件一样使用目标对象分派(dispatch)一个 svelte 事件(使用 createEventDispatcher
创建)?
即在处理程序端接收 event.target.value
而不是 event.detail。
最佳答案
是的,这是可能的,但涉及一些黑客攻击。
您可以查看 svelte 源代码以了解事件调度的工作原理。我将在下面概述关键部分。
假设我们有两个组件,Inner
和 Outer
。
<!-- 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 代码,您将看到:
inner.$$.callbacks["foo"]
持有事件处理程序 [ src ]- 当您单击按钮并调用
dispatch
时,它只会读取inner.$$.callbacks["foo"]
以获取潜在的处理程序,如果找到,则调用它们以CustomEvent
作为参数 [ src ]
设置 customEvent.target
的唯一方法是使用 element.dispatchEvent(customEvent)
分派(dispatch)该自定义事件。但是整个过程都没有用到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 - 是否可以使用目标对象分派(dispatch) svelte 自定义事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66982839/