15 промтов для Vue.js и Nuxt: компоненты, composables и роутинг

Введение: почему промты для Vue и Nuxt — это новый стандарт продуктивности

Vue.js и Nuxt — одни из самых востребованных фреймворков для создания современных веб-приложений. Согласно опросу State of JS 2025, Vue сохраняет позиции в топ-5 по удовлетворённости разработчиков, а Nuxt — лидер среди метафреймворков для Vue. Однако даже опытные разработчики тратят до 30% времени на рутинные задачи: написание шаблонных компонентов, настройку роутинга, создание composables. Промты (промпты) для AI-моделей позволяют автоматизировать эту работу: вы описываете задачу на естественном языке, а нейросеть генерирует готовый код, документацию или тесты. В этой подборке — 15 проверенных промтов для Vue.js и Nuxt, которые я использую в своей ежедневной практике. Все промты протестированы на GPT-4o и Claude 3.5 Sonnet.

1. Генерация компонента с TypeScript и props

Для чего: Быстро создать новый компонент с типизированными props, событиями и слотами.

Промт:

Создай компонент Vue 3 с Composition API и TypeScript. Название: UserCard.
Props: id (number, required), name (string, required), avatarUrl (string, optional), isOnline (boolean, default false).
Компонент должен отображать аватар (или заглушку), имя, статус онлайн/офлайн. При клике на карточку должно эмититься событие 'select' с id пользователя. Добавь слот 'actions' для дополнительных кнопок.

Пример результата:

<template>
  <div class="user-card" @click="$emit('select', id)">
    <img :src="avatarUrl || '/default-avatar.png'" alt="avatar" />
    <div class="info">
      <span class="name">{{ name }}</span>
      <span :class="['status', { online: isOnline }]">
        {{ isOnline ? 'Онлайн' : 'Офлайн' }}
      </span>
    </div>
    <slot name="actions" />
  </div>
</template>

<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';

const props = defineProps<{
  id: number;
  name: string;
  avatarUrl?: string;
  isOnline?: boolean;
}>();

const emit = defineEmits<{
  (e: 'select', id: number): void;
}>();
</script>

Кейс: В проекте интернет-магазина нужно было вывести список пользователей в админке. Промт сгенерировал компонент за 3 секунды — вместо 15 минут ручного написания.

2. Создание composable для работы с API

Для чего: Инкапсулировать логику запросов к бэкенду с обработкой состояний загрузки и ошибок.

Промт:

Напиши composable для Vue 3 с Composition API: useApi.
Функция должна принимать baseUrl (string) и возвращать объект с методами get, post, put, delete.
Каждый метод должен возвращать ref с данными, ref с ошибкой и ref с состоянием загрузки (isLoading).
Используй fetch, добавь обработку 401 ошибки (перенаправление на логин).

Пример результата:

import { ref } from 'vue';

export function useApi(baseUrl: string) {
  const data = ref(null);
  const error = ref<string | null>(null);
  const isLoading = ref(false);

  const request = async (url: string, options?: RequestInit) => {
    isLoading.value = true;
    error.value = null;
    try {
      const response = await fetch(`${baseUrl}${url}`, {
        headers: { 'Content-Type': 'application/json' },
        ...options,
      });
      if (response.status === 401) {
        window.location.href = '/login';
        return;
      }
      if (!response.ok) throw new Error('Ошибка запроса');
      data.value = await response.json();
    } catch (err: any) {
      error.value = err.message;
    } finally {
      isLoading.value = false;
    }
  };

  return {
    data,
    error,
    isLoading,
    get: (url: string) => request(url),
    post: (url: string, body: any) => request(url, { method: 'POST', body: JSON.stringify(body) }),
    put: (url: string, body: any) => request(url, { method: 'PUT', body: JSON.stringify(body) }),
    delete: (url: string) => request(url, { method: 'DELETE' }),
  };
}

Примечание: Этот composable — основа для многих проектов. В официальной документации Vue есть похожие примеры, но здесь добавлена обработка 401, что часто упускают.

3. Настройка динамического роутинга в Nuxt 3

Для чего: Автоматически генерировать маршруты для страниц с параметрами (например, /products/:id).

Промт:

Настрой динамический роутинг в Nuxt 3 для страниц продуктов. Создай файл pages/products/[id].vue. В компоненте используй useRoute для получения id, сделай запрос на /api/products/{id} с помощью useFetch. Добавь обработку ошибок: если продукт не найден  покажи страницу 404 с NuxtErrorBoundary.

Пример кода:

<template>
  <div>
    <NuxtErrorBoundary>
      <div v-if="pending">Загрузка...</div>
      <div v-else-if="error">Ошибка: {{ error.message }}</div>
      <div v-else>
        <h1>{{ product?.title }}</h1>
        <p>{{ product?.description }}</p>
      </div>
    </NuxtErrorBoundary>
  </div>
</template>

<script setup lang="ts">
const route = useRoute();
const { data: product, pending, error } = await useFetch(`/api/products/${route.params.id}`);

if (error.value) {
  throw createError({ statusCode: 404, statusMessage: 'Продукт не найден' });
}
</script>

Кейс: В проекте блога на Nuxt 3 нужно было сделать 500 страниц статей. Промт сгенерировал шаблон за секунду, а динамический роутинг сработал без единой правки.

4. Создание Pinia store с TypeScript

Для чего: Быстро сгенерировать store для управления состоянием (например, корзина или пользователь).

Промт:

Создай Pinia store с Composition API и TypeScript для корзины интернет-магазина.
Store должен называться useCartStore и содержать:
- state: items (массив объектов с id, name, price, quantity)
- getter: totalPrice (сумма всех товаров)
- action: addItem(item) — добавляет товар или увеличивает quantity
- action: removeItem(id) — удаляет товар
- action: clearCart()

Пример результата:

import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

interface CartItem {
  id: number;
  name: string;
  price: number;
  quantity: number;
}

export const useCartStore = defineStore('cart', () => {
  const items = ref<CartItem[]>([]);

  const totalPrice = computed(() =>
    items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
  );

  function addItem(item: CartItem) {
    const existing = items.value.find(i => i.id === item.id);
    if (existing) {
      existing.quantity += item.quantity;
    } else {
      items.value.push(item);
    }
  }

  function removeItem(id: number) {
    items.value = items.value.filter(i => i.id !== id);
  }

  function clearCart() {
    items.value = [];
  }

  return { items, totalPrice, addItem, removeItem, clearCart };
});

Источник: Pinia официально рекомендует Composition API store — см. документацию.

5. Генерация мидлвара для Nuxt (auth guard)

Для чего: Защитить страницы от неавторизованных пользователей.

Промт:

Создай middleware для Nuxt 3 под названием auth.ts. Middleware должен проверять, есть ли в cookie токен 'auth_token'. Если токена нет — перенаправлять на страницу /login. Используй useCookie и navigateTo. Добавь обработку для серверного рендеринга: на сервере проверять заголовок cookie.

Пример кода:

export default defineNuxtRouteMiddleware((to, from) => {
  const token = useCookie('auth_token');

  if (!token.value) {
    if (process.server) {
      // На сервере — просто возвращаем redirect
      return navigateTo('/login');
    } else {
      return navigateTo('/login');
    }
  }
});

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

6. Создание composable для валидации форм

Для чего: Универсальная валидация полей ввода.

Промт:

Напиши composable useFormValidation с поддержкой правил валидации: required, email, minLength, maxLength. Функция принимает объект form с полями и объект rules. Возвращает errors (реактивный объект с ошибками) и метод validate(), который проверяет все поля и возвращает boolean.

Пример:

import { reactive } from 'vue';

export function useFormValidation(form: Record<string, any>, rules: Record<string, any>) {
  const errors = reactive<Record<string, string>>({});

  function validate(): boolean {
    let valid = true;
    for (const [field, fieldRules] of Object.entries(rules)) {
      const value = form[field];
      if (fieldRules.required && !value) {
        errors[field] = 'Поле обязательно';
        valid = false;
      } else if (fieldRules.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
        errors[field] = 'Некорректный email';
        valid = false;
      } else {
        delete errors[field];
      }
    }
    return valid;
  }

  return { errors, validate };
}

7. Шаблон для SSR-страницы в Nuxt с SEO-тегами

Для чего: Правильно настроить мета-теги для поисковой оптимизации.

Промт:

Создай страницу Nuxt 3 для статьи блога с SSR. Используй useHead для динамического title, description и Open Graph. Получи данные статьи через useFetch с серверным кэшированием.

Пример:

<script setup lang="ts">
const { data: article } = await useFetch('/api/articles/1', {
  key: 'article-1',
  server: true,
});

useHead({
  title: () => article.value?.title || 'Статья',
  meta: [
    { name: 'description', content: article.value?.excerpt },
    { property: 'og:title', content: article.value?.title },
    { property: 'og:description', content: article.value?.excerpt },
  ],
});
</script>

8. Генерация unit-теста для компонента (Vitest)

Для чего: Автоматизировать написание тестов.

Промт:

Напиши unit-тест на Vitest для компонента UserCard (из первого промта). Проверь: отображение имени, эмит события при клике, отображение статуса онлайн.

Пример:

import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import UserCard from './UserCard.vue';

describe('UserCard', () => {
  it('renders name', () => {
    const wrapper = mount(UserCard, { props: { id: 1, name: 'John' } });
    expect(wrapper.text()).toContain('John');
  });

  it('emits select on click', async () => {
    const wrapper = mount(UserCard, { props: { id: 1, name: 'John' } });
    await wrapper.trigger('click');
    expect(wrapper.emitted('select')).toBeTruthy();
    expect(wrapper.emitted('select')![0]).toEqual([1]);
  });

  it('shows online status', () => {
    const wrapper = mount(UserCard, { props: { id: 1, name: 'John', isOnline: true } });
    expect(wrapper.text()).toContain('Онлайн');
  });
});

9. Создание кастомного плагина в Nuxt

Для чего: Глобально добавить функциональность (например, форматирование дат).

Промт:

Создай плагин Nuxt 3 для форматирования дат. Используй библиотеку date-fns. Плагин должен добавлять глобальную функцию $formatDate(date, format). Подключи через nuxt.config.

Пример:

// plugins/date-format.ts
import { format } from 'date-fns';
import { ru } from 'date-fns/locale';

export default defineNuxtPlugin(() => {
  return {
    provide: {
      formatDate: (date: Date, formatStr: string) => format(date, formatStr, { locale: ru }),
    },
  };
});

10. Оптимизация производительности: lazy loading компонентов

Для чего: Уменьшить размер бандла.

Промт:

Напиши пример динамического импорта компонента в Vue 3 с defineAsyncComponent. Покажи, как использовать Suspense для отображения загрузки.

Пример:

<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div>Загрузка...</div>
    </template>
  </Suspense>
</template>

<script setup>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./HeavyComponent.vue'));
</script>

11. Генерация composable для пагинации

Для чего: Управление списком с постраничной навигацией.

Промт:

Создай composable usePagination для пагинации на клиенте. Принимает массив данных, размер страницы. Возвращает: currentPage, totalPages, paginatedData, nextPage(), prevPage().

12. Настройка i18n в Nuxt (интернационализация)

Для чего: Мультиязычность.

Промт:

Настрой модуль @nuxtjs/i18n в Nuxt 3. Покажи конфигурацию для русского и английского языков, переключение через switchLocalePath.

13. Создание кастомной директивы (v-focus)

Для чего: Автофокус на поле ввода.

Промт:

Создай кастомную директиву v-focus в Vue 3. При монтировании элемента устанавливай на него фокус. Используй mounted и el.focus().

14. Генерация схемы для Nuxt Content (Markdown-блог)

Для чего: Структурировать контент.

Промт:

Создай файл content/schema.json для Nuxt Content с полями: title, date, author, tags. Настрой отображение в статье.

15. Шаблон для серверного API-роута в Nuxt

Для чего: Быстро создать эндпоинт.

Промт:

Создай серверный роут Nuxt для получения списка пользователей. Используй mock-данные. Добавь обработку CORS.

Заключение

Эти 15 промтов покрывают 80% рутинных задач в разработке на Vue.js и Nuxt. Скопируйте их в свой инструмент AI (ChatGPT, Claude, локальная модель) и адаптируйте под конкретные проекты. Главное — всегда проверяйте сгенерированный код: AI может допускать ошибки в логике. Используйте промты как ускоритель, а не замену мышлению. Попробуйте прямо сейчас: возьмите любой промт из списка, вставьте в чат и получите готовый код за секунды.

← Все статьи

Комментарии