You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte手风琴式时间线组件开发:插槽Props传递与模式实现问题

Svelte 时间线(手风琴)组件开发问题

我正在开发一个时间线组件,本质是支持不同模式的进阶手风琴组件:

  • single模式:同一时间仅能展开一个项
  • multiple模式:可同时展开多个项

问题1:如何实现如下结构的组件

<Timeline mode="single">
  <TimelineItem id="01-23-2004">
    <button slot="title">Title</button>
    <div slot="content">Content</div>
  </TimelineItem>

  <TimelineItem id="01-24-2004">
    <button slot="title">Title</button>
    <div slot="content">Content</div>
  </TimelineItem>
</Timeline>

问题2:能否向插槽内的每个元素传递prop?

比如当<slot {mode}>被多个<TimelineItems>替代时,能否将{mode}传递给每个<TimelineItem>?


当前代码实现

timeline.svelte

<script lang="ts">
  import { setContext } from "svelte";
  import { writable, type Writable } from "svelte/store";

  export let open = "single";
  switch (open) {
    case "single":
      // 响应式上下文
      let activeId: Writable<string> = writable<string>("");
      setContext<Writable<string>>("activeId", activeId);
      break;

    case "multiple":
      break;

    default:
      throw new Error("Invalid timeline mode");
  }
</script>

<div class="flex overflow-y-auto flex-col p-4">
  <slot {open} />
</div>

timeline-item.svelte

<script lang="ts">
  import { getContext } from "svelte";
  import type { Writable } from "svelte/store";

  export let id: string; // 日期
  let activeId = getContext<Writable<string>>("activeId");
  $: active = $activeId === id;

  export let open: string;

  export let handleClick = () => {
    if (active) {
      activeId.set("");
      return;
    }

    activeId.set(id);
  };
</script>

<div class="flex">
  <div>
    <slot name="title" {handleClick} />
  </div>

  {open}

  {#if active}
    <div class="pl-10">
      <slot name="content" />
    </div>
  {/if}
</div>

+page.svelte

<script lang="ts">
  import TimelineItem from "$lib/timeline/timeline-item.svelte";
  import Timeline from "$lib/timeline/timeline.svelte";
</script>

<Timeline open="single">
  <TimelineItem id="01-20-2006" let:open> <!-- ERROR -->
    <svelte:fragment slot="title" let:handleClick>
      <button slot="title" on:click={handleClick}>Title</button>
    </svelte:fragment>
    <p slot="content">Content</p>
  </TimelineItem>

  <TimelineItem id="01-20-2004" let:open> <!-- ERROR -->
    <svelte:fragment slot="title" let:handleClick>
      <button slot="title" on:click={handleClick}>Title</button>
    </svelte:fragment>
    <p slot="content">Content</p>
  </TimelineItem>

  <TimelineItem id="01-20-2005" let:open> <!-- ERROR -->
    <svelte:fragment slot="title" let:handleClick>
      <button slot="title" on:click={handleClick}>Title</button>
    </svelte:fragment>
    <p slot="content">Content</p>
  </TimelineItem>
</Timeline>

报错信息

Property 'open' is missing in type '{ id: string; }' but required in type '{ id: string; open: string; handleClick?: (() => void) | undefined; }'. 7:4:1 ts2741
Property 'default' does not exist on type '{ title: { handleClick: () => void; }; content: {}; }'. 7:40:1 ts2339

内容的提问来源于stack exchange,提问作者user22385988

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:59:59