Как создавать необычные элементы списка в Astro
14 июня 2023 г.Вы, наверное, видели много веб-сайтов, использующих крутые маркеры вместо обычных скучных. Как они это делают? Есть ли эффективный и простой способ создавать причудливые маркеры при написании действительно простого кода?
Ответ есть — с Astro это возможно. Вы можете просто написать уценку, и в результате получится хорошо отформатированный маркер, созданный с помощью SVG.
Прежде чем мы начнем
Я предполагаю, что вы знаете, как использовать Astro и вы знаете, как интегрировать MDX в Astro. Если нет, не волнуйтесь. Просто следуйте инструкциям, и вы получите общее представление о том, как все работает, а затем выясните, как использовать Astro и MDX.
(Я собираюсь создать курс для него в ближайшее время, потому что Astro фантастический — это лучший генератор статических сайтов, который я когда-либо использовал).
Шаги
Если вы использовали Astro, вы, вероятно, можете сделать вывод об этих шагах из примера, который я показал вам выше.
Они:
- Вы создаете компонент
<List>
, который принимает ваши маркеры в содержимом<slot>
. - Вы берете эти маркеры в компоненте
<List>
. - Вы просматриваете каждый элемент списка и добавляете SVG перед маркером.
Вот как выглядит разметка;
---
const { bullet } = Astro.props
---
<ul class='List'>
{
listItems.map(item => (
<li>
<!-- Your SVG here -->
<Fragment set:html={item.innerHTML} />
</li>
))
}
</ul>
Самое замечательное в этом то, что вы можете добавлять дополнительные свойства, такие как fill
, stroke
и другие вещи, чтобы изменить SVG, чтобы он отображался с достаточной уникальностью.
Вот несколько примеров, когда я изменил fill
SVG для Magical Dev School.
Я собираюсь показать вам, как создать простую версию, которая позволит вам вставить нужный вам SVG. Мы не будем рассматривать такие сложные вещи, как добавление fill
и stroke
и другие условия!
Схватка за пули в Astro
Astro позволяет получить содержимое элемента <slot>
внутри вашего компонента.
Вы можете получить этот контент, вызвав функцию render
. Вы увидите строку
, содержащую HTML, который будет создан.
---
const html = await Astro.slots.render('default')
console.log(html)
---
Далее происходит волшебство
Вы можете проанализировать эту строку HTML и получить элементы списка — так же, как и стандартный document.querySelectorAll
с помощью JavaScript.
Для этого вам нужно преобразовать строку HTML в структуру, подобную DOM.
Здесь можно использовать множество парсеров. Я выбрал для своих проектов node-html-parser
. (Потому что это быстро).
---
import { parse } from 'node-html-parser'
const html = await Astro.slots.render('default')
const root = parse(html)
---
После синтаксического анализа HTML вы можете получить элементы списка с помощью querySelectorAll
.
---
// ...
const listItems = root.querySelectorAll('li')
---
Затем вы можете сопоставить элементы списка и создать свой причудливый список.
---
// ...
---
<ul class='List'>
{
listItems.map(item => (
<li>
<!-- Your SVG goes here -->
<Fragment set:html={item.innerHTML} />
</li>
))
}
</ul>
Добавление SVG
Самый простой способ добавить SVG в компонент — использовать встроенные SVG.
Если вы хотите переключаться между различными типами элементов списка, вы можете попросить пользователя передать свойство bullet
. Затем вы встраиваете другой SVG в зависимости от значения bullet
.
---
const { bullet } = Astro.props
// ...
---
<ul class='List'>
{
listItems.map(item => (
<li>
{ bullet === 'green-check' && <svg> ... </svg> }
{ bullet === 'red-cross' && <svg> ... </svg> }
{ bullet === 'star' && <svg> ... </svg> }
<Fragment set:html={item.innerHTML} />
</li>
))
}
</ul>
Конечно, это не лучший способ...
Лучший способ добавить SVG
Лучше всего добавить SVG через компонент. Когда вы делаете это, вы можете просто передать SVG и позволить компоненту SVG обрабатывать логику SVG.
---
import SVG from './SVG.astro'
const { bullet } = Astro.props
// ...
---
<ul class='List'>
{
listItems.map(item => (
<li>
<SVG name={bullet} />
<Fragment set:html={item.innerHTML} />
</li>
))
}
</ul>
Самый простой способ создать этот компонент SVG — встроить в него код SVG, как в примере, показанном выше.
---
// SVG component
const { name } = Astro.props
---
{ bullet === 'green-check' && <svg> ... </svg> }
{ bullet === 'red-cross' && <svg> ... </svg> }
{ bullet === 'star' && <svg> ... </svg> }
Но это не лучший способ, потому что вам все равно придется использовать условные операторы...
А SVG может быть заведомо большим и сложным, поэтому вместо этого вы создадите что-то громоздкое...
Лучший способ создать компонент SVG
Лучший способ:
- Храните SVG в папке
svgs
- Захватите SVG из этой папки при передаче
name
в компонент<SVG>
Как это сделать, лучше оставить для другого урока, так как мы углубимся в другую тему.
Если вы хотите узнать, как я создаю компонент SVG
, а также как я использую Astro и Svelte, прокрутите вниз и оставьте свой адрес электронной почты в форме ниже. Я хотел бы поделиться с вами больше!
Причудливая проверка
Что очень здорово в этом подходе, так это то, что вы даже можете использовать Astro для проверки типа bullet
, который вы передаете в <List>
, fill code>,
штрих
и другие нужные вам свойства.
Конечно, вы можете сделать это и с помощью Typescript. Я просто показываю вам, что вы можете использовать обычный JS, если хотите, чтобы все было просто.
const validators = {
bullet: [{
type: 'star',
fill: ['yellow', 'green', 'red', 'blue'],
stroke: ['black', 'transparent'],
}]
}
validate({ ...Astro.props })
function validate () {
// Check props against validators
}
Вот и все!
Надеюсь, сегодня вы узнали что-то новое!
:::информация Первоначально опубликовано в моем блоге.
:::
Не стесняйтесь посетить его, если вы хотите, чтобы эти статьи доставлялись на вашу электронную почту из первых рук, когда они будут опубликованы! 🙂.
Оригинал