Is there a good way to style HTML elements and re-expose all of their events in a Svelte component?

huangapple go评论66阅读模式
英文:

Is there a good way to style HTML elements and re-expose all of their events in a Svelte component?

问题

Sure, here's the translated content:

如何在 Svelte 组件中为 HTML 元素添加样式并重新公开它们的所有事件?(本质上,我正在寻找 Svelte 实现 styled-components 的方法)

例如,我尝试为常规的 HTML button 添加样式并将其公开为可重用组件:

<script>
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();
</script>

<button
  on:click={() => dispatch("click")}
  on:mouseover={() => dispatch("mouseover")}
  {/* ...以及其他事件 */}
>
  <slot />
</button>

<style>
  button {
    /* ... */
  }
</style>

有没有办法避免必须让 button HTML 元素上的每个事件都调用 dispatch 以传播事件到父组件?有没有更简单的方法?

我尝试搜索,大多数地方都建议我使用 CSS-in-JS,但我不想放弃在 Svelte 中纯粹编写样式所带来的所有优化(较小的捆绑包大小,更好的性能等等)。

英文:

How would I go about styling HTML elements and re-exposing all of their events in a Svelte component? (essentially, I'm looking for the Svelte way to do styled-components)

For example, I'm trying to style a regular HTML button and expose it a reusable component:

&lt;script&gt;
  import { createEventDispatcher } from &quot;svelte&quot;;

  const dispatch = createEventDispatcher();
&lt;/script&gt;

&lt;button
  on:click={() =&gt; dispatch(&quot;click&quot;)}
  on:mouseover={() =&gt; dispatch(&quot;mouseover&quot;)}
  {/* ...and so on for every other event */}
&gt;
  &lt;slot /&gt;
&lt;/button&gt;

&lt;style&gt;
  button {
    /* ... */
  }
&lt;/style&gt;

Is there any way to avoid having to make every single event on the button HTML element call dispatch to propagate the event through the parent? Is there a simpler way?

I've tried searching, and most places point me to just use CSS-in-JS, but I don't want to forego all the optimizations having my styles written purely in Svelte give me (lower bundle sizes, better performance, etc.)

答案1

得分: 1

你可以通过仅列出事件而无需事件处理程序来转发事件:

&lt;button {...$$restProps} on:click on:focus on:hover ...&gt;

无需分发,但目前您无法自动转发所有事件,仍然需要将它们列出。(该问题链接)

属性通过$$restProps传递,其中包括所有未明确定义的属性(不包括事件)。(文档链接)

英文:

You can forward events by just listing them without event handler:

&lt;button {...$$restProps} on:click on:focus on:hover ...&gt;

No need to dispatch, but you currently cannot automatically forward all events, they still need to be listed. (Issue on that)

Properties are passed via $$restProps, which includes all not explicitly defined properties (not events). (Docs)

答案2

得分: -1

你可以使用**$$restProps对象**将按钮的所有事件和属性传递给组件:

脚本

<script>
  import { createEventDispatcher } from "svelte";

  const dispatch = createEventDispatcher();

  export let $$restProps;
</script>

<button on:click={() => dispatch("click")} {...$$restProps}>
  <slot />
</button>

样式

<style>
  button {
    /* ... */
  }
</style>

然后像这样使用该组件:

<StyledButton class="my-button" on:click={() => console.log("clicked!")}>
  Click me!
</StyledButton>
英文:

You can use the $$restProps object to pass all the events and properties of
the button to the component:

Script

&lt;script&gt;
  import { createEventDispatcher } from &quot;svelte&quot;;

  const dispatch = createEventDispatcher();

  export let $$restProps;
&lt;/script&gt;

&lt;button on:click={() =&gt; dispatch(&quot;click&quot;)} {...$$restProps}&gt;
&lt;slot /&gt;

</button>

Styling

&lt;style&gt;
  button {
    /* ... */
  }
&lt;/style&gt;

Then use this component like this:

&lt;StyledButton class=&quot;my-button&quot; on:click={() =&gt; console.log(&quot;clicked!&quot;)}&gt;
  Click me!
&lt;/StyledButton&gt;

huangapple
  • 本文由 发表于 2023年5月17日 17:40:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76270665.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定