Создание и регистрация компонентов

Учимся разбивать интерфейс на переиспользуемые компоненты, импортировать их и собирать из них дерево приложения.

Компонент — самостоятельный кусок интерфейса со своим шаблоном, логикой и стилями, который можно переиспользовать сколько угодно раз, как тег.

Зачем дробить на компоненты

Большое приложение неудобно держать в одном файле. Его разбивают на компоненты: Header, UserCard, Button. Каждый отвечает за свою часть, его можно переиспользовать и тестировать отдельно. Из компонентов складывается дерево: корневой App содержит дочерние, те — свои.

Создаём дочерний компонент

Компонент — это обычный .vue-файл. Создадим UserCard.vue:

<!-- UserCard.vue -->
<template>
  <div class="card">
    <h3>Карточка пользователя</h3>
    <p>Здесь будут данные</p>
  </div>
</template>

<script setup>
// логика компонента
</script>

<style scoped>
.card { border: 1px solid #ddd; padding: 12px; }
</style>

Регистрация и использование

В <script setup> регистрация локальная и автоматическая: достаточно импортировать компонент, и он сразу доступен как тег в шаблоне. Никаких дополнительных объявлений не нужно:

<!-- App.vue -->
<template>
  <h1>Пользователи</h1>
  <UserCard />
  <UserCard />
</template>

<script setup>
import UserCard from './components/UserCard.vue'
</script>

Здесь UserCard использован дважды — каждый экземпляр независим, со своим состоянием. Так и проявляется переиспользование.

Именование компонентов

ПравилоПример
Имя файла и тег — в PascalCaseUserCard.vue, <UserCard />
Минимум два слова (чтобы не путать с HTML-тегами)<BaseButton />, не <Button />
Компонент без содержимого — самозакрывающийся<UserCard />

Модель дерева на JS

Дерево компонентов — это обычная вложенность. Посчитаем, например, сколько всего узлов в небольшом дереве приложения:

const app = {
  name: "App",
  children: [
    { name: "Header", children: [] },
    { name: "UserList", children: [
      { name: "UserCard", children: [] },
      { name: "UserCard", children: [] },
    ] },
  ],
};

function countNodes(node) {
  let total = 1;
  for (const child of node.children) total += countNodes(child);
  return total;
}

console.log("Всего компонентов в дереве:", countNodes(app));

Вывод:

Всего компонентов в дереве: 5

Итог

  • Компонент — переиспользуемый кусок UI в отдельном .vue-файле.
  • В <script setup> достаточно импортировать компонент — регистрация автоматическая.
  • Имена компонентов — в PascalCase и из двух слов, чтобы не путать с HTML-тегами.
  • Из компонентов складывается дерево с корнем App.
Проверьте себя
1. Как зарегистрировать дочерний компонент при использовании <script setup>?
AОбъявить его в опции components
BПросто импортировать его — в script setup регистрация автоматическая
CВызвать app.component() в main.js
DДобавить его в массив globalComponents
2. Почему компоненту рекомендуют давать имя из двух слов, например BaseButton?
AТак требует синтаксис Vue
BЧтобы имя не конфликтовало с существующими и будущими HTML-тегами
CДвусловные имена работают быстрее
DЭто нужно только для TypeScript
3. Что произойдёт, если использовать <UserCard /> дважды в одном шаблоне?
AVue выдаст ошибку дублирования
BПоявятся два независимых экземпляра компонента, каждый со своим состоянием
CВторой экземпляр будет игнорирован
DОба экземпляра разделят общее состояние
Поддержать проект