Svelte:使用调度程序转发事件与传入处理函数,哪个是最佳实践?
Svelte: Event forwarding with dispatcher vs passing in handling function, which is best practice?
假设一个外部组件包含一个内部组件,我们希望将来自内部组件的事件传播到外部组件。在不使用商店的情况下,有两种方法可以做到这一点:
方法一:使用dispatcher转发事件
Inner.svelte:使用 Svelte 的调度程序调度原始事件的重新打包版本:
<input type="text" on:input={callDispatcher} />
const dispatcher = createEventDispatcher();
function callDispatcher(e) {
dispatcher("mymsg", {
foo: e.target.value
});
}
Outer.svelte: 监听 Inner 的派发事件:
<Inner on:mymsg={handler} />
function handler(e) {
alert(e.detail.foo);
}
方法 2:将 Outer 的处理程序直接传递给 Inner
Inner.svelte: 接受外部传入的处理程序:
export let externalHandler;
<input type="text" on:input={externalHandler} />
Outer.svelte:当Inner感兴趣的事件发生时,会调用Outer的handler:
<Inner externalHandler={handler} />
function handler(e) {
alert(e.target.value);
}
问题
哪种做法更好?方法1的dispatcher似乎是一个不必要的中间层,不仅增加了代码,还丢失了原有的事件信息。但奇怪的是,Svelte 教程提到方法 1 而不是方法 2。
没有真正的区别,您确实可以同时使用两者。
但是,方法 2 不适用于 native 元素,让您混合使用这两种方法,您会得到这样的鳕鱼:
<Child clickHandler="{childClick}" />
<button on:click="{buttonClick}">click</button>
您必须始终记住何时使用哪个,而如果您使用调度程序方法,这将始终相同
<Child on:click="{childClick}" />
<button on:click="{buttonClick}">click</button>
额外的调度程序代码是一种权衡。
添加 link 到 Why use createEventDispatcher?(Svelte GitHub 问题)评论很好地涵盖了这一点,恕我直言:
By using createEventDispatcher
, you are telling the compiler to compile your component in such a way that any events it emits adheres to the typical CustomEvent interface. This isn't that big of a deal if you are just dealing with Svelte, but I gather that if you are compiling Svelte components to be used elsewhere as web components, your compiled component will be compiled with an interface other frameworks will understand (…).
这是有道理的。
前面的线程:
It's now (Mar 2019) a lot easier to have props that are callbacks in Svelte 3, so you'll probably be using events less anyway.
这表明两者共存可能有一些进化原因。
还有一件事:对于事件,一个绑定到自定义事件接口和 .detail
包装(这就是重点!)。对于外部组件来说,这似乎是额外的复杂性,而使用函数引用可以制作更细长的 API.
如果最后要进行函数引用,请注意 linked 问题中的 <Thing1 {onClick} />
shorthand。
编辑:好像没那么简单。 Events are not emitted from components ...(2019 年 6 月开放)表明 Svelte 事件不能完全用于 Web 组件。在这个问题解决之前,调度可能介于两个世界之间。不是很标准。不是很习惯。
我发现使用 function prop 更简单、更惯用,并且大部分时间对我来说都能优雅地完成工作。
<!-- App.svelte -->
<Button onClick={handleClick}></Button>
<!-- Button.svelte -->
<button on:click={onClick}>
Click me
</button>
我使用事件转发的唯一情况是当我需要做...嗯...事件转发。 :)(来自深层嵌套组件)
<!-- App.svelte -->
<Outer on:customEvent={handleCustomEvent} />
<!-- Outer.svelte -->
<Inner on:customEvent />
<!-- Inner.svelte -->
<Button on:customEvent />
<!-- Button.svelte -->
<button on:click={() => dispatch('customEvent')}>
Click me
</button>
参考:https://www.donielsmith.com/blog/2020-04-21-props-vs-event-dispatcher-svelte-3/
免责声明:我是 Svelte 的新手,来自 React。
假设一个外部组件包含一个内部组件,我们希望将来自内部组件的事件传播到外部组件。在不使用商店的情况下,有两种方法可以做到这一点:
方法一:使用dispatcher转发事件
Inner.svelte:使用 Svelte 的调度程序调度原始事件的重新打包版本:
<input type="text" on:input={callDispatcher} />
const dispatcher = createEventDispatcher();
function callDispatcher(e) {
dispatcher("mymsg", {
foo: e.target.value
});
}
Outer.svelte: 监听 Inner 的派发事件:
<Inner on:mymsg={handler} />
function handler(e) {
alert(e.detail.foo);
}
方法 2:将 Outer 的处理程序直接传递给 Inner
Inner.svelte: 接受外部传入的处理程序:
export let externalHandler;
<input type="text" on:input={externalHandler} />
Outer.svelte:当Inner感兴趣的事件发生时,会调用Outer的handler:
<Inner externalHandler={handler} />
function handler(e) {
alert(e.target.value);
}
问题
哪种做法更好?方法1的dispatcher似乎是一个不必要的中间层,不仅增加了代码,还丢失了原有的事件信息。但奇怪的是,Svelte 教程提到方法 1 而不是方法 2。
没有真正的区别,您确实可以同时使用两者。 但是,方法 2 不适用于 native 元素,让您混合使用这两种方法,您会得到这样的鳕鱼:
<Child clickHandler="{childClick}" />
<button on:click="{buttonClick}">click</button>
您必须始终记住何时使用哪个,而如果您使用调度程序方法,这将始终相同
<Child on:click="{childClick}" />
<button on:click="{buttonClick}">click</button>
额外的调度程序代码是一种权衡。
添加 link 到 Why use createEventDispatcher?(Svelte GitHub 问题)评论很好地涵盖了这一点,恕我直言:
By using
createEventDispatcher
, you are telling the compiler to compile your component in such a way that any events it emits adheres to the typical CustomEvent interface. This isn't that big of a deal if you are just dealing with Svelte, but I gather that if you are compiling Svelte components to be used elsewhere as web components, your compiled component will be compiled with an interface other frameworks will understand (…).
这是有道理的。
前面的线程:
It's now (Mar 2019) a lot easier to have props that are callbacks in Svelte 3, so you'll probably be using events less anyway.
这表明两者共存可能有一些进化原因。
还有一件事:对于事件,一个绑定到自定义事件接口和 .detail
包装(这就是重点!)。对于外部组件来说,这似乎是额外的复杂性,而使用函数引用可以制作更细长的 API.
如果最后要进行函数引用,请注意 linked 问题中的 <Thing1 {onClick} />
shorthand。
编辑:好像没那么简单。 Events are not emitted from components ...(2019 年 6 月开放)表明 Svelte 事件不能完全用于 Web 组件。在这个问题解决之前,调度可能介于两个世界之间。不是很标准。不是很习惯。
我发现使用 function prop 更简单、更惯用,并且大部分时间对我来说都能优雅地完成工作。
<!-- App.svelte -->
<Button onClick={handleClick}></Button>
<!-- Button.svelte -->
<button on:click={onClick}>
Click me
</button>
我使用事件转发的唯一情况是当我需要做...嗯...事件转发。 :)(来自深层嵌套组件)
<!-- App.svelte -->
<Outer on:customEvent={handleCustomEvent} />
<!-- Outer.svelte -->
<Inner on:customEvent />
<!-- Inner.svelte -->
<Button on:customEvent />
<!-- Button.svelte -->
<button on:click={() => dispatch('customEvent')}>
Click me
</button>
参考:https://www.donielsmith.com/blog/2020-04-21-props-vs-event-dispatcher-svelte-3/
免责声明:我是 Svelte 的新手,来自 React。