Компоненты и автоимпорт
Компоненты в Nuxt пишутся так же, как во Vue, но импортировать их не нужно. Всё, что лежит в папке app/components/, Nuxt находит сам и разрешает использовать в любом шаблоне по имени файла. Это и называется автоимпортом.
Карточка статьи
Создайте компонент командой:
npx nuxi add component PostCardПоявится файл app/components/PostCard.vue. Замените содержимое:
<!-- app/components/PostCard.vue -->
<script setup lang="ts">
defineProps<{
post: { id: number; title: string; text: string }
}>()
</script>
<template>
<article class="post-card">
<h3>
<NuxtLink :to="`/posts/${post.id}`">{{ post.title }}</NuxtLink>
</h3>
<p>{{ post.text }}</p>
</article>
</template>Компонент получает статью через свойство post и выводит заголовок-ссылку и текст.
Использование
Замените разметку статьи в списке app/pages/posts/index.vue:
<!-- app/pages/posts/index.vue -->
<template>
<section>
<h2>Статьи</h2>
<PostCard v-for="post in posts" :key="post.id" :post="post" />
</section>
</template>Строки import PostCard from ... нет, но страница /posts выглядит как раньше: Nuxt подставил компонент по имени файла. Редактор тоже знает о нём — подсказки и проверка типов работают.
Компоненты в подпапках
Подпапки помогают навести порядок, а имя компонента складывается из пути:
| Файл | Имя в шаблоне |
|---|---|
app/components/PostCard.vue | <PostCard> |
app/components/post/Comments.vue | <PostComments> |
app/components/post/CommentForm.vue | <PostCommentForm> |
app/components/admin/Menu.vue | <AdminMenu> |
Создайте app/components/post/Comments.vue для будущих комментариев:
<!-- app/components/post/Comments.vue -->
<template>
<section>
<h3>Комментарии</h3>
<p>Комментариев пока нет.</p>
</section>
</template>На странице статьи его выводят как <PostComments />.
Ленивая загрузка
Если к имени компонента добавить слово Lazy, его код загрузится отдельным файлом только тогда, когда компонент понадобится:
<!-- app/pages/posts/[id].vue -->
<script setup lang="ts">
const showComments = ref(false)
</script>
<template>
<article>
<button @click="showComments = true">Показать комментарии</button>
<LazyPostComments v-if="showComments" />
</article>
</template>Код комментариев скачивается после нажатия кнопки, поэтому первая загрузка страницы легче.
Только в браузере
Компонент, которому нужны window или localStorage, оборачивают в <ClientOnly>: на сервере он пропускается и появляется после загрузки в браузере.
Частая ошибка
Файл app/components/post/Card.vue не подключится как <Card> — его имя <PostCard>, потому что к имени добавляется название папки. Если компонент «не найден», откройте Nuxt DevTools, вкладку Components: там видны настоящие имена всех компонентов.