Условное обнаружение слота по умолчанию в svelte

У меня есть стройный компонент со слотом по умолчанию и именованным слотом. У меня есть экземпляр этого компонента, я использую именованный слот и использую медленное значение по умолчанию внутри оператора {#if}, проверяющего логическое значение.

Проблема внутри моего компонента: у меня есть логика, которая проверяет слот по умолчанию и отображает некоторые отступы и границы. Кажется, даже когда логическое значение ложно и {#if} ложно, медленное значение по умолчанию все еще существует, просто пустое.

Ребенок:

const hasDefaultSlot = Object.keys($$slots).includes('default');

Родитель:

<MyComponent>
<div slot = "header"> header </div>
{#if checked}
  <div>body</div>
{/if}
</MyComponent>

Я ожидаю, что когда checked будет ложным, Object.keys($$slots).includes('default') будет ложным, или $$slots.default будет ложным, или что $$slots.default будет не логическим значением, а объектом, содержащим другую информацию, которую я могу использовать, чтобы проверить, пуст ли он.

К сожалению, похоже, что компилятор Svelte считает результат утверждения #if всегда истинным, даже несмотря на то, что он меняется в реальном времени и поначалу является ложным.

Не имея возможности условно определить слот, я всегда визуализирую тело и стили тела для элемента карты, что портит CSS для компонента.

🤔 А знаете ли вы, что...
С Svelte можно создавать прогрессивные веб-приложения (PWA) с поддержкой оффлайн-режима.


148
1

Ответ:

Решено

Все внутри компонента, что не назначено явно именованному слоту, становится частью слота по умолчанию. {#if} также является частью слота, поэтому слот всегда будет установлен.

Вы можете обойти это, добавив дополнительное свойство флага, как вы упомянули.


В Svelte 5 все будет немного по-другому, благодаря более гибкой системе сниппетов. Как и в случае со слотом по умолчанию, здесь имеется неявное присвоение свойству children, но это свойство может быть назначено, как и любое другое, поэтому содержимое может передаваться условно.

{#snippet body()}
  <div>body</div>
{/snippet}
<MyComponent children = {checked ? body : undefined}>
  {#snippet header()}
    <div>header</div>
  {/snippet}
</MyComponent>