Encodera

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

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

Оглавление

Composables и утилиты

Composable — функция, которая прячет повторяющуюся логику с реактивными данными, например счётчик лайков. Её имя принято начинать с use. Во Vue такие функции импортируют вручную, а Nuxt подключает их автоматически из папки app/composables/. Для обычных функций без реактивности есть соседняя папка app/utils/.

Свой composable

npx nuxi add composable useLikes

Команда создаст app/composables/useLikes.ts. Замените содержимое:

// app/composables/useLikes.ts
export function useLikes() {
  const likes = ref(0)
 
  function like() {
    likes.value++
  }
 
  return { likes, like }
}

ref тоже не импортирован: функции Vue (ref, computed, watch, onMounted и другие) Nuxt подключает сам.

Использование

Добавьте кнопку лайка в карточку app/components/PostCard.vue:

<!-- app/components/PostCard.vue -->
<script setup lang="ts">
defineProps<{
  post: { id: number; title: string; text: string }
}>()
 
const { likes, like } = useLikes()
</script>
 
<template>
  <article class="post-card">
    <h3>
      <NuxtLink :to="`/posts/${post.id}`">{{ post.title }}</NuxtLink>
    </h3>
    <button @click="like">Нравится: {{ likes }}</button>
  </article>
</template>

У каждой карточки на странице /posts свой счётчик: функция вызывается заново для каждого компонента и создаёт новый ref.

Утилиты

Функции без реактивности кладут в app/utils/. Создайте файл app/utils/formatDate.ts:

// app/utils/formatDate.ts
export function formatDate(date: string) {
  return new Date(date).toLocaleDateString('ru-RU', {
    day: 'numeric',
    month: 'long',
    year: 'numeric'
  })
}

Теперь в любом компоненте можно написать {{ formatDate('2025-03-14') }} и получить «14 марта 2025 г.» без импорта.

Что подключается автоматически

ОткудаЧто
Vueref, computed, watch, onMounted и другие
NuxtuseRoute, navigateTo, useFetch, useState и другие
app/composables/Экспорты файлов верхнего уровня
app/utils/Экспорты файлов верхнего уровня
app/components/Компоненты

Явный импорт тоже работает, если так понятнее: import { useLikes } from '~/composables/useLikes'.

Где вызывать composables

Composables Nuxt (useRoute, useFetch, useState) и ваши, которые их используют, вызывают в <script setup>, в другом composable, в middleware или плагине. Вызов внутри setTimeout или после await в обычной функции может закончиться ошибкой «A composable that requires access to the Nuxt instance was called outside of a plugin».

Частая ошибка

Nuxt просматривает только файлы верхнего уровня app/composables/. Файл app/composables/posts/usePosts.ts в подпапке автоматически не подключится, и шаблон выдаст ошибку usePosts is not defined. Держите composables прямо в папке или подключайте файл из подпапки явным импортом.

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

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