将点击事件传递到动态创建的 <svelte:component/> 中

12

当父组件中的图标/按钮被点击时,我基本上需要能够触发一个或多个组件(通过svelte:component动态添加)中的某些内容。例如,我需要挂钩下面用**标识的部分:

<script>
 let charts = [
    ChartA,
    ChartB,
    ChartC
  ];
</script>
{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={**HowToPassClickEventToComponent**}></div>
        <div class="content">
        <svelte:component this={charts[i]} {**clickedEvent**}/>
        </div>
    </div>
{/each}

我尝试使用一个属性数组来实现某些功能,但每个组件在数组更改时都会被通知,所以这不是很干净。

我已经在Google和StackOverflow上进行了搜索,并在Svelte Discord频道中提出了这个问题,但目前没有找到解决方法。

Svelte Repl展示了问题

这似乎是一个非常简单的要求,但经过几天的尝试后我仍然卡住了,因此任何有关如何将事件传递到动态组件的建议都将不胜感激。


让每个组件定义并添加自己的 on:click 处理程序。并查看 svelte:component。 - voscausa
我不知道为什么你的代码没有起作用,但是如果你像这样使用 bind:<svelte:component this={charts[i]} bind:event={flag}/> 它就可以正常工作。 - voscausa
添加绑定:似乎会产生差异,但这会导致所有组件在按钮被点击时都发生变化(由于单个标志变量),这不是所需的,并且会导致回到原始问题的道路上,这真的很丑陋,因为每个组件都必须检查它是否是点击的目标。谢谢,我很感激您的建议。 - Minty
我现在明白为什么你的代码没有起作用了。你必须使用:event={flag}而不是event:{flag}。 - voscausa
谢谢,我也会关注那个。 - Minty
显示剩余5条评论
1个回答

20

您可以像这样执行

<script>
    import ChartA from './ChartA.svelte'
    import ChartB from './ChartB.svelte'
    import ChartC from './ChartC.svelte'
    let charts = [
        ChartA,
        ChartB,
        ChartC
    ];
    let events = [];
</script>

<style>
    .icon{
        width:60px;
        height:30px;
        background-color:grey;
    }
</style>

{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={e=>events[i] = e}>Click</div>
        <div class="content">
            <svelte:component this={charts[i]} event={events[i]}/>
        </div>
    </div>
{/each}

将事件作为数据传递可能有些不寻常。更符合惯用法的做法是在父组件中设置一些状态以响应事件,并将该状态向下传递。

或者,如果子组件确实需要自行响应事件,则可以采用以下方法...

<script>
    import ChartA from './ChartA.svelte'
    import ChartB from './ChartB.svelte'
    import ChartC from './ChartC.svelte'
    let charts = [
        ChartA,
        ChartB,
        ChartC
    ];
    let instances = []; 
</script>

<style>
    .icon{
        width:60px;
        height:30px;
        background-color:grey;
    }
</style>

{#each charts as chart, i}
    <div class="wrapper">
        <div class="icon" on:click={e => instances[i].handle(e)}>Click</div>
        <div class="content">
            <svelte:component
                this={charts[i]}
                bind:this={instances[i]}
            />
        </div>
    </div>
{/each}

每个子组件都要导出一个handle方法:

<script>
    let event;
    export function handle(e){
        event = e;
    };
</script>

1
嗨,Rich,你的第二个建议非常适合我所需,我非常感激。同时也谢谢你介绍 Svelte(真是太棒了)。 - Minty
1
是的,非常好。 - voscausa
2
在经过大量搜索之后,这个答案告诉我在调用子组件函数时使用export是必要的,终于能够停止把头砸在键盘上了。 :) - glormph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接