🚀 Быстрый совет по Svelte: стилизация слотов с условными именами
Эта статья изначально была опубликована на моей странице Dev.to
👋 Привет, мир!
В моем предыдущем посте я описал, как вы можете выборочно стилизовать дочерние элементы <slot>
. Теперь мы собираемся немного уменьшить масштаб и посмотреть, как мы можем стилизовать сами контейнеры <slot>
.
Вы, вероятно, обнаружите, что делаете это, когда работаете с несколькими слотами имен, которые также являются необязательными.
Насколько мне известно, есть 3 основных способа сделать это:
- Стиль обернутого компонента
- Стиль, основанный на имени
[slot="..."]
- Используйте условные слоты
Теперь давайте рассмотрим каждый из них на примере компонента <Modal>
с дополнительным слотом actions
для действий формы:
Нетерпеливый? Суть в том, чтобы использовать условные слоты 🤓
1. Стиль обернутого компонента
Вероятно, самое простое из всех, мы можем обернуть слот тегом, а затем применить стили к этому родительскому тегу:
<section> <div> <slot /> </div> <footer> <slot name="actions" /> </footer> </section>
<style lang="postcss"> section { background: white; border-radius: 1rem; box-shadow: 0 0.4rem 0.5rem rgba(0, 0, 0, 0.15); } div { padding: 2rem; } div :global(> :first-child) { margin-top: 0; } div :global(> :last-child) { margin-bottom: 0; } footer { background: #ececec; border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem; padding: 1.25rem 2rem; } </style>
Затем мы можем использовать этот компонент следующим образом:
<h1>With slot content</h1> <Modal> <p>Hello, World!</p> <div slot="actions"> <button>Click me</button> </div> </Modal>
<h1>Without slot content</h1> <Modal> <p>Hello, World!</p> </Modal>
Проблемная часть этого решения заключается в том, что если в слоте нет контента, он все равно будет отображаться, что, конечно, не то, что нам действительно нужно:
Это происходит из-за того, что тег <footer>
существует в DOM и, таким образом, к нему применен стиль, поэтому мы видим серое поле, а не ничего, как мы ожидали.
Я предполагаю, что это первый подход большинства людей при создании именованных слотов (как это было у меня), поэтому читайте дальше, чтобы найти лучшие решения, если это тоже ваша история!
Посмотрите это в Svelte REPL здесь.
2. Стиль на основе имени [slot="..."]
Единственная разница здесь в том, что мы собираемся стилизовать слот, используя только имя слота в качестве селектора. Для этого сначала удалите из слота оберточный тег <footer>
:
<section>
<div>
<slot></slot>
</div>
- <footer>
- <slot name="actions"></slot>
- </footer>
+ <slot name="actions"></slot>
</section>
Далее мы будем использовать синтаксис [slot="..."]
в сочетании с модификатором :global
для выбора слота по его имени. Таким образом, мы можем стилизовать слот без добавления дополнительной разметки:
-footer {
+section :global([slot="actions"]) {
/* ...styling remains the same... */
}
Теперь вы можете видеть, что нижний колонтитул скрыт, как мы и ожидали:
На самом деле, поскольку в слот не передается контент, он даже не отображается в DOM:
Этот конкретный подход полезен, когда вам нужно напрямую стилизовать сам слот, и его можно использовать в сочетании с условными слотами ниже.
Посмотрите это в Svelte REPL здесь.
3. Используйте условные слоты
Это, вероятно, «правильный» способ решения этой проблемы в большинстве случаев, поскольку он не требует каких-либо странных волшебств CSS, как в предыдущем примере.
Мы просто заключаем слот в условное выражение, что заставит его отображать слот и его содержимое только в том случае, если слоту было предоставлено содержимое в потребляющем компоненте:
{#if $$slots.actions}
<footer>
<slot name="actions"></slot>
</footer>
{/if}
Свойство $$slots
— это свойство, которое Svelte предоставляет всем компонентам и которое представляет собой словарь именованных слотов (узнайте больше о $$slots
здесь).
Причина, по которой я считаю это «правильным» способом решения этой проблемы, заключается в том, что никакая разметка не отображается в браузере, и вам не нужно делать какие-то хакерские :global
модификации, как в примере № 2.
Кроме того, вы можете добавить переходы/анимацию, когда он смонтирован, как и другие элементы Svelte, что довольно удобно 😻
Посмотрите это в Svelte REPL здесь.
🎬 Плавник
Ну это все народ! 🐰
Надеюсь, это даст вам немного больше ясности при работе со стилем именованных слотов в Svelte!
Подводя итог, вы захотите использовать условные слоты для большинства случаев использования, поскольку это самое чистое решение из трех, и при этом вы можете применять определенный стиль/структуру к самому слоту.
Есть другие советы, идеи, отзывы или исправления? Дайте мне знать в комментариях! 🙋♂️
Не забудьте подписаться на меня на Dev.to (danawoodman), Twitter (@danawoodman) и/или Github (danawoodman)!
Фото автора Joshua Aragon на Unsplash