如何解决是否可以使用目标对象分派苗条的自定义事件?
是否可以使用像原生浏览器事件这样的目标对象来分派一个 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)
调度该自定义事件。但是 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);
});
}
};
}
,
根据 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 举报,一经查实,本站将立刻删除。