ViteTemplateHTML

HTML-компоненти

Цей документ описує підключення компонентів, передачу параметрів, вивід контенту.

Підключення компонента:

Тег компонента є назвою html файлу компонента

src/html/components/Header/Header.html

<Header/>

Просте підключення (без передачі контента або параметрів):

<Header/>

Передавання пропсів (параметрів):

<Header title="Заголовок" isLogo="true"/>

Звичайні пропси доступні тільки в компоненті, у який їх передали. Якщо параметр треба прокинути в дочірні компоненти, використовуйте префікс deep:.

<Card label="Visible only inside Card" />
<Card deep:label="Visible inside nested components" />

Передавання контенту (будь що, текст, інші компоненти, html):

Переданий контент буде доступний в компоненті в змінній {{children}}

<Button type="link" isActive="true">Button</Button>

<Button type="link" isActive="true">
   <span>Button text</span>
   <Icon name="arrow-right" />
</Button>

<Header className="header">
   <NavMenu activeLink="1"/>
</Header>

Named slots:

Контент без <template slot="..."> потрапляє в {{children}}. Іменовані блоки передаються через <template slot="name">, а в компоненті рендеряться через <slot name="name">.

// Виклик компонента
<Card title="Named slots">
   <template slot="actions">
      <Button>Save</Button>
   </template>
   <p>Default body content</p>
   <template slot="footer">
      Footer content
   </template>
</Card>

// Card.html
<article class="card">
   <header>
      <h2>{{title}}</h2>
      <slot name="actions"></slot>
   </header>
   <div>{{children}}</div>
   <footer>
      <slot name="footer">
         Default footer
      </slot>
   </footer>
</article>

Об'єкт slots також доступний у виразах як {{slots.footer}}, але для звичайного рендера з fallback зручніше використовувати тег <slot>.

Компоненти з namespace:

Компонент можна викликати за назвою файлу або через шлях від папки компонентів. Namespace корисний, коли в різних папках є компоненти з однаковим basename.

src/html/components/UI/Button/Button.html
src/html/components/Forms/Button/Button.html

<UI.Button>UI button</UI.Button>
<Forms.Button>Form button</Forms.Button>

// Якщо basename унікальний, старий синтаксис теж працює:
<Header />

Icon component:

Компонент <Icon /> рендерить іконку з icon font. Значення name мапиться на CSS-клас _icon-name.

// fonts-converter/icons/arrow-right.svg -> ._icon-arrow-right
<Icon name="arrow-right" />
<Icon name="phone" class="text-primary" />
<UI.Icon name="phone" class="text-xl" label="Phone" />

// Dynamic attrs також підтримуються
<Icon name="arrow-right" iconAttrs="{ 'data-icon': 'arrow-right' }" />

Якщо label не передано, іконка виводиться як декоративна з aria-hidden="true". Для доступної іконки передайте label.

Використання параметрів що передаються через пропси:

// src/html/components/Button/Button.html

<button type="button" {{isActive != "true" ? "disabled" : ''}}>
  {{children}}
</button>

<header class="{{className}}">
  {{children}}
</header>

Локальні змінні компонента:

Блок <script define> створює змінні тільки для поточного компонента. Вкладені компоненти не бачать ці змінні автоматично.

// ParentCard.html
<script define>
   const title = propsTitle || 'Default title'
</script>
<h2>{{title}}</h2>
<ChildCard />

Якщо дочірньому компоненту потрібне це значення, передайте його явно через prop або через deep:.

<ChildCard title="{{title}}" />
<ChildCard deep:title="{{title}}" />

Безпечний доступ до пропсів та глобальні об'єкти:

Безпечний доступ (Safe Access)

Якщо змінна не передана в компонент, вона повертає undefined замість помилки. Це дозволяє використовувати значення за замовчуванням через оператор ||.

// Якщо title не передано, виведеться 'Default Title'
<h1>{{ title || 'Default Title' }}</h1>

Глобальні об'єкти (Math, JSON, etc.)

У виразах доступні стандартні глобальні об'єкти JavaScript.

// Використання Math
<div class="width-{{ Math.round(width) }}"></div>

// Використання JSON
<div data-config="{{ JSON.stringify(config) }}"></div>

Складні вирази

Інтерполяція {{...}} підтримує вкладені {}, [], (), рядки, template literals і регулярні вирази всередині JS-виразу.

<title>{{title ? `${title} | ${SITE_NAME}` : SITE_NAME}}</title>
<div data-config='{{JSON.stringify({ title, options: { theme: "dark" } })}}'></div>
<p>{{/\d{2,4}/.test(code) ? 'Valid' : 'Invalid'}}</p>

Динамічні атрибути:

Спеціальний пропс attributes дозволяє передати об'єкт атрибутів, які будуть розгорнуті на кореневому елементі компонента.

<Button attributes="{{ { id: 'btn-1', 'data-type': 'primary' } }}">Click</Button>

// Результат:
<button id="btn-1" data-type="primary">Click</button>