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

Vue 3 и Nuxt 3 прочно заняли нишу современного frontend-разработчика: по данным State of JS 2023, Vue остаётся одним из самых используемых фреймворков, а Composition API стал стандартом для новых проектов. Но даже опытные разработчики тратят часы на рутинные задачи: написание каркаса компонентов, типизацию props, настройку роутинга и организацию store. Правильно сформулированные промты для генеративных AI-инструментов (ChatGPT, Claude, Copilot) могут сократить эту работу в разы. В этой подборке — 12 практических промтов, которые я использую в реальной работе. Каждый промт включает постановку задачи, сам текст запроса и пример результата.

1. Базовый компонент с props и emits

Задача: быстро создать переиспользуемый UI-компонент с типизированными props и событиями.
Промт: «Создай компонент Vue 3 (Composition API, script setup) для кнопки с загрузкой. Принимает props: loading (boolean), disabled (boolean), variant (primary/secondary). Эмитит событие click. Используй TypeScript».
Пример результата:

<template>
  <button
    class="btn"
    :class="`btn--${variant}`"
    :disabled="disabled || loading"
    @click="$emit('click')"
  >
    <span v-if="loading" class="spinner" />
    <slot />
  </button>
</template>
<script setup lang="ts">
defineProps<{
  loading?: boolean;
  disabled?: boolean;
  variant?: 'primary' | 'secondary';
}>();
defineEmits<{ (e: 'click'): void }>();
</script>

2. Composable для работы с API

Задача: централизовать загрузку данных с обработкой ошибок и отменой запроса.
Промт: «Напиши composable useFetchData, который принимает URL и параметры, возвращает data, error, loading и метод refetch. Используй fetch с AbortController для отмены запроса».
Пример результата:

import { ref, onUnmounted } from 'vue';
export function useFetchData<T>(url: string) {
  const data = ref<T | null>(null);
  const error = ref<string | null>(null);
  const loading = ref(false);
  let controller: AbortController | null = null;
  const fetchData = async () => {
    controller?.abort();
    controller = new AbortController();
    loading.value = true;
    error.value = null;
    try {
      const res = await fetch(url, { signal: controller.signal });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      data.value = (await res.json()) as T;
    } catch (e: any) {
      if (e.name !== 'AbortError') error.value = e.message;
    } finally {
      loading.value = false;
    }
  };
  onUnmounted(() => controller?.abort());
  return { data, error, loading, refetch: fetchData };
}

3. Роутинг с параметрами в Nuxt

Задача: создать страницу товара с динамическим маршрутом и SEO-заголовком.
Промт: «Создай страницу продукта в Nuxt 3: динамический роут [id].vue, подгрузка данных через useFetch, установка title через useSeoMeta. Добавь кнопку „Назад“».
Пример результата:

<script setup lang="ts">
const route = useRoute();
const { data: product } = await useFetch(`/api/products/${route.params.id}`);
useSeoMeta({ title: product.value?.title ?? 'Товар' });
</script>
<template>
  <div>
    <NuxtLink to="/catalog">← Назад</NuxtLink>
    <h1>{{ product?.title }}</h1>
  </div>
</template>

4. Компонент с v-model

Задача: реализовать кастомный инпут, который работает через v-model.
Промт: «Создай компонент SearchInput в Vue 3. Поддерживает v-model, очистку, иконку поиска, emits update:modelValue».
Пример результата:

<script setup lang="ts">
const model = defineModel<string>({ default: '' });
</script>
<template>
  <div class="search">
    <input v-model="model" type="text" placeholder="Поиск..." />
    <button v-if="model" @click="model = ''">✕</button>
  </div>
</template>

5. Provide / Inject

Задача: пробросить текущего пользователя в глубоко вложенные компоненты без props drilling.
Промт: «Создай composable useUser (provide/inject). В app.vue получай пользователя и провайди его. В дочернем компоненте инжекти и выводи имя».
Пример результата:

// useUser.ts
import { provide, inject, ref, type Ref } from 'vue';
const KEY = Symbol('user');
export function provideUser(user: Ref<{ name: string } | null>) {
  provide(KEY, user);
}
export function useUser() {
  return inject<Ref<{ name: string } | null>>(KEY) ?? ref(null);
}

6. Пользовательская директива

Задача: добавить анимацию появления при прокрутке.
Промт: «Создай директиву v-visible в Vue 3: при пересечении с viewport добавляет класс visible и вызывает callback». Пример результата:

export const vVisible = {
  mounted(el: HTMLElement, binding: { value?: () => void }) {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        el.classList.add('visible');
        binding.value?.();
        observer.disconnect();
      }
    });
    observer.observe(el);
    el._observer = observer;
  },
  unmounted(el: HTMLElement) {
    el._observer?.disconnect();
  },
};

7. Pinia store с actions

Задача: организовать корзину с типизированным store и persist.
Промт: «Напиши Pinia store для корзины: state cart: Product[], actions add, remove, setQty, getter totalPrice. Используй setup-синтаксис. Продукт: id, title, price».
Пример результата:

export const useCartStore = defineStore('cart', () => {
  const cart = ref<{ id: number; title: string; price: number; qty: number }[]>([]);
  const totalPrice = computed(() => cart.value.reduce((s, p) => s + p.price * p.qty, 0));
  function add(item: { id: number; title: string; price: number }) {
    const existing = cart.value.find(p => p.id === item.id);
    if (existing) existing.qty++;
    else cart.value.push({ ...item, qty: 1 });
  }
  return { cart, totalPrice, add };
});

8. Переходы и анимации списка

Задача: добавить плавное появление/удаление элементов списка.
Промт: «Опиши компонент TodoList с . Элементы появляются с fade и slide, удаляются с animation. Используй CSS».
Пример результата:

<template>
  <TransitionGroup name="list" tag="ul">
    <li v-for="item in items" :key="item.id">{{ item.text }}</li>
  </TransitionGroup>
</template>
<style>
.list-enter-active, .list-leave-active { transition: all 0.4s ease; }
.list-enter-from, .list-leave-to { opacity: 0; transform: translateX(20px); }
</style>

9. Nuxt middleware для авторизации

Задача: защитить страницы от неавторизованных пользователей.
Промт: «Создай middleware auth в Nuxt 3. Если нет токена в localStorage, редирект на /login. Используй defineNuxtRouteMiddleware».
Пример результата:

export default defineNuxtRouteMiddleware((to) => {
  const token = localStorage.getItem('token');
  if (!token) return navigateTo({ path: '/login', query: { redirect: to.fullPath } });
});

10. Server routes в Nuxt

Задача: быстро прототипировать API endpoint.
Промт: «Создай server/api/user.ts в Nuxt, который возвращает JSON с задержкой 500мс и обрабатывает GET и POST».
Пример результата:

export default defineEventHandler(async (event) => {
  await new Promise(resolve => setTimeout(resolve, 500));
  if (event.method === 'GET') return { name: 'John', role: 'admin' };
  if (event.method === 'POST') {
    const body = await readBody(event);
    return { message: `Hi, ${body.name}!` };
  }
  return { error: 'Method not allowed' };
});

11. Типизация компонентов и v-model в TypeScript

Задача: сделать строгую типизацию для сложных форм.
Промт: «Создай компонент AddressForm с полями street, city, zip. Типизируй props и emit update:modelValue, используя defineModel с generic».
Пример результата:

<script setup lang="ts">
interface Address { street: string; city: string; zip: string; }
const address = defineModel<Address>({ required: true });
</script>
<template>
  <input v-model="address.street" placeholder="Улица" />
</template>

12. Оптимизация рендеринга: shallowRef и v-memo

Задача: увеличить производительность списка с тысячей строк.
Промт: «Опиши пример использования shallowRef для массива объектов в Vue 3. Покажи, когда следует избегать глубокой реактивности, добавь v-memo для статичных элементов».
Пример результата:

<script setup>
const rows = shallowRef([]); // обновление rows.value = [] не будет глубоко реактивным
</script>
<template>
  <div v-for="row in rows" v-memo="[row.id]">{{ row.text }}</div>
</template>

Заключение

Предложенные промты покрывают 80% повседневных задач Vue-разработчика: от создания компонентов до организации store. Используйте их как отправную точку — уточняйте контекст, добавляйте требования к стилю кода и тестированию. Подбирая точные формулировки, вы получаете не просто шаблонный код, а решение, вписанное в архитектуру вашего проекта. Подписывайтесь на блог Asibiont — здесь мы разбираем такие практические приёмы без воды.

← Все статьи

Комментарии

Читайте также

STM32 + ASI Biont: пошаговая интеграция Blue Pill и Nucleo с AI-агентом через UART, MQTT и Modbus

31 июля 2026

Как я построил фриланс-карьеру за 90 дней: путь инженера поддержки с курсом по фрилансу на asibiont.com

31 июля 2026

Severance: почему сценарий сериала «Разделение» стал реальностью в 2026 году

31 июля 2026

Интеграция Datadog с ASI Biont: как AI-агент автоматизирует мониторинг и DevOps-рутину

31 июля 2026

Digital Transformation — цифровая трансформация бизнеса: курс для лидеров изменений на asibiont.com

31 июля 2026

Интеграция Wise с ASI Biont: платежи через ИИ-агента, автоматизация без кода и трансграничные выплаты

31 июля 2026

Большие модели и цена миллиона токенов: как стоимость AI влияет на бизнес в 2026 году

31 июля 2026

Промты для Swift и iOS: SwiftUI, UIKit, Core Data и Combine — как мы ускорили разработку в 2 раза

31 июля 2026

Интеграция датчика влажности почвы Rain/Soil Moisture Sensor с ASI Biont: умный полив без программирования

31 июля 2026