svelte - 多个组件具有各自独立的交互和值

svelte - multiple components with their own isolated interactions and values

我创建了一个切换按钮组件,以便我可以在项目的各个地方使用它:

<style>
  .butt{
    background:blue;
  }
  .butt.active{
    background:lightblue;
  }
</style>

<script>
  function toggle(e){
    console.log('toggle')
    console.log(e.target.id)
    let el = document.getElementById(e.target.id)
    el.classList.toggle("active")
  }
</script>

<div
on:click={toggle}
class="butt"
id="abc"
>sample button</div>

然后我将它添加到我的 app.svelte:

<script>
  import Togglebutt from "./Togglebutt.svelte"
</script>

{#each [1,2,3] as thing (thing)}
  <Togglebutt />
{/each}

我这里有 2 个问题:

  1. 每次点击按钮,它只会触发第一个按钮,不会触发第 2 个和第 3 个按钮。
  2. 添加了 css class active,但按钮从未呈现为预期的颜色。

我该如何解决这 2 个问题?

第一个问题是因为当您执行 document.getElementById(e.target.id) 时,您将有三个按钮,每个按钮的 ID 都是 abc,它将 always return 它找到的第一个。这个问题可以通过传递一个 id 作为 属性 来解决,这样你的每个切换都有一个唯一的 id。

另一个问题是 Svelte 会删除所有在标记中未明确使用 的样式声明,active class 无处使用您的标记,因此它将被删除。

使用 Svelte 时,像这样直接操作 DOM 通常不是一个好主意,而是依赖组件的状态和 Svelte 的内部逻辑来为您管理。

这意味着在您的脚本中您将有一个跟踪组件状态的变量:

<script>
  export let toggled = false
</script> 

并且您使用此状态有条件地将 class 添加到元素

<div class:active={toggled}></div>

您可以更进一步,将 shorthand 用于条件 class,这需要变量和 class 同名:<div class:toggled></div>

这为我们提供了

的完整组成部分
<style>
  .butt {
    background:blue;
  }
  .butt.toggled {
    background:lightblue;
  }
</style>

<script>
  export let toggled = false

  function toggle() {
    toggled = !toggled
  }
</script>

<div
  on:click={toggle}
  class="butt"
  class:toggled
>sample button</div>