传递回调是最直接的。光。简单的。在大多数情况下,回调可以做到,而且 IMO 更可取。
不过,您只能传递一个回调,而同一事件可以有多个侦听器。
<script>
import { onMount } from 'svelte'
import Beeper from './Beeper.svelte'
let beeper
onMount(() => {
const disposes = [
beeper.$on('beep', () => console.log('dynamic A')),
beeper.$on('beep', () => console.log('dynamic B'))
]
return () => disposes.forEach(fn => fn())
})
</script>
<Beeper on:beep={() => console.log('inline')} bind:this={beeper} />
使用独立组件可能更有趣?
const beeper = new Beeper({ target: document.body })
beeper.$on('beep', ...)
beeper.$on('beep', ...)
事件也可以更容易代理:
Proxy.svelte
<script>
import Beeper from './Beeper.svelte'
</script>
<Beeper on:beep />
App.svelte
<script>
import Proxy from './Proxy.svelte'
</script>
<Proxy on:beep={() => console.log('beep')} />
另一方面,事件代理可能会很麻烦:
Proxy.svelte
<script>
import Beeper from './Beeper.svelte'
</script>
<!-- callbacks are all in the $$props bag, but I have to know every
event that I want to proxy -->
<Beeper {...$$props} on:beep />
而且它们甚至可以说更容易代理:
<script>
import Beeper from './Beeper.svelte'
export let onBeep
</script>
<Beeper {onBeep} />
此外,我不确定您是否可以使用 Svelte 的自定义元素风格进行回调,因此您可能会遇到那里的事件。
在某些情况下,您可能更喜欢事件 API 的一致性(尤其是当您的组件非常模仿现有 DOM 元素时)、优雅或美观的原因。
就个人而言,我通常只使用回调,除非回调不起作用。这种情况很少见。
啊!不,您不能在插槽上举办活动。但是你也不能真的有回调,不是吗?
<slot onBeep={onBeep} />
这将使onBeep 函数在消费者组件中作为let:onBeep 可用:
<SlotBeeper let:onBeep>
{@debug onBeep}
<AnotherCmp {onBeep} />
</SlotBeeper>