如何在 svelte 中共享多插槽及其 parents 之间的状态

how to share state between multi slots and their parents in svelte

我想用 svelte 创建一个手风琴折叠 UI 组件,并像这样实现:

<collapse activeItem="1">
  <collapse-item title="标题1" name="1">代码是写出来给人看的,附带能在机器上运行</collapse-item>
  <collapse-item title="标题2" name="2">代码是写出来给人看的,附带能在机器上运行2</collapse-item>
  <collapse-item title="标题3" name="3">代码是写出来给人看的,附带能在机器上运行3</collapse-item>
</collapse>

看起来像这样:

当我们更改 collapse 的 activeItem 道具的值时,collapse-item 具有相同名称道具的值将展开。

但是我真的很难找到一种方法让 collapse-item 知道他们的 parent 折叠组件的 prop activeItem 的值。

我还可以像这样在 collapse-item 上添加一个 activeItem 道具:

<collapse activeItem="1">
  <collapse-item title="标题1" activItem="1" name="1">代码是写出来给人看的,附带能在机器上运行</collapse-item>
  <collapse-item title="标题2" activItem="1" name="2">代码是写出来给人看的,附带能在机器上运行2</collapse-item>
  <collapse-item title="标题3" activItem="1" name="3">代码是写出来给人看的,附带能在机器上运行3</collapse-item>
</collapse>

但是这种方式不是那么优雅

对于这种情况,我真的需要一些建议。

您可以设置一个store (a store is an object that allows reactive access to a value via a simple store contract) in context,然后组件的子组件(包括开槽内容)可以使用上下文。

尝试转到 svelte.dev 并使编辑器看起来像这样:

Collapse.svelte:

<script>
    import { active } from './stores.js';
    import Item from './Item.svelte';
    const indexes = [1,2,3];
    function handleClick(e) {
        const index = Number(e.target.dataset.index);
        active.set(index === $active ? 0 : index);
    }
</script>

<ul on:click={handleClick}>
    {#each indexes as index}
        <Item index={index}/>
    {/each}
</ul>
CollapseItem.svelte:

<script>
    import { active } from './stores.js';
    export let index;
    let active_val;
    const active_unsubscribe = active.subscribe(val => active_val = val);
</script>

<style>
    .active {color: red}
</style>

<li class:active={index === active_val} data-index={index}>Number {index}</li>
stores.js:

import { writable } from 'svelte/store';
export const active = writable();

希望这能让您知道该怎么做!