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

Svelte:如何强制{#if}块内组件挂载?解决搜索失效问题

解决可折叠侧边栏中未挂载组件的上下文订阅问题

问题核心是Collapsible组件用{#if}控制插槽内容时,未展开状态下插槽内的MyControl会被销毁,无法订阅Sidebar的上下文,导致搜索功能失效。以下是两种可行的解决方法:

方法1:用CSS控制显示隐藏替代{#if}

通过CSS控制内容的显示/隐藏而非销毁组件,让插槽内的MyControl始终保持挂载状态,从而能正常订阅上下文。修改Collapsible.svelte:

<script>
  import { slide } from 'svelte/transition';
  export let expanded = false;
</script>

<style>
  .collapsible-wrapper {
    overflow: hidden;
  }
</style>

<div class="collapsible-wrapper">
  {#key expanded}
    {#if expanded}
      <div transition:slide>
        <slot />
      </div>
    {:else}
      <div style="height: 0;">
        <slot />
      </div>
    {/if}
  {/key}
</div>

或者更简洁的CSS类方案:

<script>
  export let expanded = false;
</script>

<style>
  .collapsible-content {
    opacity: 0;
    height: 0;
    overflow: hidden;
    transition: opacity 0.3s, height 0.3s;
  }
  .collapsible-content.expanded {
    opacity: 1;
    height: auto;
  }
</style>

<div class="collapsible-content {expanded ? 'expanded' : ''}">
  <slot />
</div>

这样MyControl会始终处于挂载状态,能实时订阅上下文的搜索状态,折叠时也能正常响应搜索。

方法2:将搜索过滤逻辑上移

如果不想始终挂载插槽内容,可以把搜索状态的检查逻辑移到父组件,提前过滤需要显示的MyControl,再传递给Collapsible:

  1. 在Sidebar中暴露搜索状态:
<script>
  import { writable } from 'svelte/store';
  export const searchQuery = writable('');
</script>

<Searchbar bind:query={$searchQuery} />

<Collapsible>
  {#each ['hello', 'world'] as label}
    {#if $searchQuery === '' || label.includes($searchQuery)}
      <MyControl {label} />
    {/if}
  {/each}
</Collapsible>
  1. MyControl无需再订阅上下文,直接接收label即可:
<script>
  export let label;
</script>

<!-- 控件内容 -->

这种方式下,父层先处理搜索过滤,Collapsible只渲染符合条件的MyControl,避免了未挂载组件无法订阅的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:02:49