Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Компоненты и автоимпорт

Компоненты в 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: там видны настоящие имена всех компонентов.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.