Svelte, EventDispatcher или функция как значение? Что использовать?

Чтение кода в этом замечательном модальном примере: https://svelte.dev/examples#modal I ' м пытаюсь понять, в чем разница с точки зрения производительности / размера пакета / другого, если я использую:

  1. createEventDispatcher() с директивой типа on:close={()=> doSomething()} или
  2. просто передайте функцию как значение типа action={doSomething}.

Также в первом случае я не могу использовать on:close={...} на slot, верно?

Если я попробую, это даст мне эту ошибку: [!] (plugin svelte) ValidationError: <slot> cannot have directives

Что вы рекомендуете использовать?


person Fred Hors    schedule 09.06.2020    source источник
comment


Ответы (1)


Передать обратный вызов проще всего. Свет. Простой. В большинстве случаев обратный вызов может сделать, и ИМО они предпочтительнее.

Однако вы можете передать только один обратный вызов, тогда как у вас может быть несколько слушателей для одного и того же события.

<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>
person rixo    schedule 09.06.2020