Svelte自定义元素不转发事件

问题描述 投票:1回答:1

我想在我的项目中使用Tabulator,该项目尚未与Svelte集成。这是我之前已经使用过的非常完整的数据表库。但是,当我尝试使用操作按钮(编辑,删除...)创建典型列时,我一直使用它们的Custom Formatters作为字符串返回html。

格式化列的函数返回如下所示:

return '<ul class="actions_row"><li><custom-button on:click={handleClick}>Edit</custom-button></li></ul>';

<custom-button />是使用<svelte:options>创建的自定义元素,并通过index.html<script src="lib/CustomButton.js"></script>)添加到项目中。

自定义按钮显示在表中,但是它无法转发事件。似乎该组件无法在其自身范围之外进行通信。

svelte tabulator svelte-3 svelte-component
1个回答
1
投票

您的自定义格式化程序返回的字符串将被处理为“普通” HTML,因此Svelte语法不再可用...即on:click是Svelte语法,将不会被浏览器处理。

我不是自定义元素专家,但是很遗憾,according to others,您试图做的事是不可能的。也就是说,您不能仅通过HTML在自定义元素上注册自定义事件侦听器。您可能必须从JS执行此操作。像这样的东西:

    <script>
      document.querySelector('custom-button')
        .addEventListener('my-event', e => {
          console.log(e.detail)
        })
    </script>

此外,请注意,Svelte中来自自定义元素的事件当前受到某些限制(请参阅this issue

因此,为了让自定义元素具有自定义事件,您必须使用某种解决方法。例如,这是一个可以触发上述片段中的侦听器的组件:

<svelte:options tag="custom-button" />

<script>
  import { onMount } from 'svelte';

  let el

  onMount(() => {
    const interval = setInterval(() => {
      let event = new CustomEvent('my-event', {
          detail: {time: Date.now()},
          bubbles: true,
          composed: true, // needed for the event to traverse beyond shadow dom
      })
      el.dispatchEvent(event)
    }, 1000)

    return () => {
      clearInterval(interval)
    }
  })
</script>

<button bind:this={el}><slot /></button>

请注意,此类代码对旧版浏览器的支持有限。

话虽如此,就您的示例而言,恰恰是这样,您显然可以通过在本机浏览器onclick而非Svelte的on:click中注册事件来使其正常工作。我仍然不是CE专家,但我的猜测是浏览器还会处理所有本机元素(例如,单击或按下CE元素)上可用的标准事件...

所以,看来这应该对您有用:

return '<ul class="actions_row"><li><custom-button onclick="handleClick">Edit</custom-button></li></ul>';

注意:onclick="handleClick"而不是on:click={handleClick}。您现在位于标准浏览器领域,因此适用常规规则,就如同使用普通<button> ... handleClick必须在范围内可用一样,等等。

© www.soinside.com 2019 - 2024. All rights reserved.