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 с
Пример результата:
<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 — здесь мы разбираем такие практические приёмы без воды.
Комментарии