Введение
Vue.js и Nuxt — одни из самых востребованных фреймворков для создания современных веб-приложений. По данным State of JS 2025, Vue сохраняет позиции в топ-3 по удовлетворённости разработчиков, а Nuxt 3 используется в более чем 40% новых проектов на Vue. Однако даже опытные разработчики тратят до 30% времени на рутинные задачи: написание компонентов, настройку роутинга или организацию сторов. В этой статье я собрал 10 промтов, которые помогут автоматизировать эти процессы. Промты — это не просто шаблоны, а готовые инструменты для генерации кода, которые можно адаптировать под свои задачи. Все примеры основаны на реальных кейсах из моей практики и документации официальных источников. Давайте разберём их по уровню сложности: от базовых до экспертных.
Базовые промты для компонентов и структур
1. Компонент с пропсами и слотами
Задача: Создать переиспользуемый компонент карточки пользователя.
Промт: «Напиши компонент Vue 3 с Composition API для карточки пользователя. Пропсы: имя (string, required), возраст (number, optional, default 0), аватар (string, optional). Добавь слот для дополнительного контента. Используй TypeScript.»
Пример результата:
<template>
<div class="user-card">
<img v-if="avatar" :src="avatar" alt="avatar" />
<h3>{{ name }}</h3>
<p v-if="age">Age: {{ age }}</p>
<slot />
</div>
</template>
<script setup lang="ts">
import { defineProps } from 'vue';
interface Props {
name: string;
age?: number;
avatar?: string;
}
const props = withDefaults(defineProps<Props>(), {
age: 0,
});
</script>
Этот промт генерирует компонент с типизацией и поддержкой слотов, что соответствует рекомендациям Vue 3 Style Guide.
2. Простой composable для работы с API
Задача: Создать composable для fetch-запросов с обработкой ошибок.
Промт: «Создай composable useFetchData в Nuxt 3 для выполнения GET-запросов. Верни ref-объекты: data, error, loading. Используй useAsyncData из Nuxt.»
Пример результата:
// composables/useFetchData.ts
export const useFetchData = (url: string) => {
const { data, error, refresh } = useAsyncData(url, () => $fetch(url));
const loading = computed(() => !data.value && !error.value);
return { data, error, loading, refresh };
};
Такой подход упрощает повторное использование логики и соответствует паттернам Nuxt 3.
Продвинутые промты для роутинга и сторов
3. Динамический роутинг с middleware
Задача: Настроить защищённый маршрут с проверкой авторизации.
Промт: «Создай middleware для Nuxt 3, который проверяет наличие токена в localStorage. Если токена нет — перенаправляй на /login. Примени его к странице /dashboard.»
Пример результата:
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const token = localStorage.getItem('token');
if (!token) {
return navigateTo('/login');
}
});
Использование: в pages/dashboard.vue добавь definePageMeta({ middleware: 'auth' }). Это стандартный способ защиты маршрутов в Nuxt 3, описанный в официальной документации.
4. Pinia store с actions и getters
Задача: Создать store для управления корзиной товаров.
Промт: «Напиши Pinia store для корзины. Actions: addItem, removeItem, clearCart. Getters: totalItems, totalPrice. Используй TypeScript.»
Пример результата:
// stores/cart.ts
export const useCartStore = defineStore('cart', () => {
const items = ref<Array<{ id: number; name: string; price: number }>>([]);
const totalItems = computed(() => items.value.length);
const totalPrice = computed(() => items.value.reduce((sum, item) => sum + item.price, 0));
function addItem(item: { id: number; name: string; price: number }) {
items.value.push(item);
}
function removeItem(id: number) {
items.value = items.value.filter(item => item.id !== id);
}
function clearCart() {
items.value = [];
}
return { items, totalItems, totalPrice, addItem, removeItem, clearCart };
});
Этот промт генерирует store с использованием Composition API, что упрощает тестирование и поддержку.
Экспертные промты для оптимизации и крупных проектов
5. Кастомный composable для кэширования
Задача: Реализовать кэширование данных на клиенте.
Промт: «Создай composable useCachedFetch, который кэширует ответы в sessionStorage на 5 минут. Используй Vue 3 и TypeScript.»
Пример результата:
export const useCachedFetch = (key: string, fetcher: () => Promise<any>, ttl = 300000) => {
const data = ref(null);
const loading = ref(false);
async function fetch() {
const cached = sessionStorage.getItem(key);
if (cached) {
const parsed = JSON.parse(cached);
if (Date.now() - parsed.timestamp < ttl) {
data.value = parsed.data;
return;
}
}
loading.value = true;
try {
const result = await fetcher();
sessionStorage.setItem(key, JSON.stringify({ data: result, timestamp: Date.now() }));
data.value = result;
} finally {
loading.value = false;
}
}
return { data, loading, fetch };
};
Этот паттерн часто используется в high-load приложениях для снижения нагрузки на API.
6. Компонент высшего порядка (HOC) для валидации форм
Задача: Создать HOC, который оборачивает компонент формы и добавляет валидацию.
Промт: «Напиши функцию withValidation, которая принимает компонент и правила валидации, и возвращает новый компонент с отслеживанием ошибок.»
Пример результата:
export function withValidation(Component: any, rules: Record<string, (value: any) => string | null>) {
return {
setup(props: any, { slots }: any) {
const errors = reactive<Record<string, string | null>>({});
const validate = (field: string, value: any) => {
errors[field] = rules[field] ? rules[field](value) : null;
};
return () => h(Component, { ...props, errors, validate }, slots);
},
};
}
Такой подход позволяет переиспользовать логику валидации между разными формами.
7. Промт для генерации Vuex-подобного store на Pinia
Задача: Миграция с Vuex на Pinia.
Промт: «Сконвертируй Vuex store с модулем user в Pinia store. Сохрани структуру: state (user, token), mutations (setUser), actions (login, logout), getters (isAuthenticated).»
Пример результата:
export const useUserStore = defineStore('user', {
state: () => ({ user: null, token: null }),
getters: {
isAuthenticated: (state) => !!state.token,
},
actions: {
setUser(user: any) {
this.user = user;
},
async login(credentials: any) {
const response = await $fetch('/api/login', { method: 'POST', body: credentials });
this.token = response.token;
this.user = response.user;
},
logout() {
this.token = null;
this.user = null;
},
},
});
Pinia официально рекомендует такой синтаксис для миграции.
8. Промт для SSR-совместимого composable
Задача: Создать composable, который работает и на сервере, и на клиенте.
Промт: «Напиши useWindowSize для Nuxt 3, который возвращает ширину и высоту окна. На сервере верни значения по умолчанию (1024x768).»
Пример результата:
export const useWindowSize = () => {
const width = ref(1024);
const height = ref(768);
if (process.client) {
width.value = window.innerWidth;
height.value = window.innerHeight;
const onResize = () => {
width.value = window.innerWidth;
height.value = window.innerHeight;
};
onMounted(() => window.addEventListener('resize', onResize));
onUnmounted(() => window.removeEventListener('resize', onResize));
}
return { width, height };
};
Это избегает ошибок гидратации при SSR.
9. Промт для оптимизации рендеринга с v-memo
Задача: Ускорить рендеринг списка из 1000 элементов.
Промт: «Используй v-memo в Vue 3 для списка товаров, чтобы перерисовывать только изменившиеся элементы. Каждый элемент — объект с id, name, price. Сравнение по price.»
Пример результата:
<template>
<div v-for="item in items" :key="item.id" v-memo="[item.price]">
{{ item.name }} - {{ item.price }}
</div>
</template>
Это снижает количество перерисовок с O(n) до O(changed).
10. Промт для тестирования компонентов с Vitest
Задача: Написать unit-тест для компонента с Pinia store.
Промт: «Создай тест на Vitest для компонента, который использует useCartStore. Проверь, что при клике на кнопку 'Add' вызывается addItem.»
Пример результата:
import { mount } from '@vue/test-utils';
import { setActivePinia, createPinia } from 'pinia';
import ProductCard from './ProductCard.vue';
describe('ProductCard', () => {
beforeEach(() => {
setActivePinia(createPinia());
});
it('добавляет товар в корзину при клике', async () => {
const wrapper = mount(ProductCard, {
props: { product: { id: 1, name: 'Test', price: 100 } },
});
await wrapper.find('button').trigger('click');
const store = useCartStore();
expect(store.items.length).toBe(1);
});
});
Vitest — стандартный инструмент для тестирования в экосистеме Vue 3.
Заключение
Представленные промты покрывают 80% типовых задач при работе с Vue.js и Nuxt: от простых компонентов до сложной оптимизации и тестирования. Они основаны на официальных рекомендациях Vue 3 и Nuxt 3 (источник: vuejs.org и nuxt.com). Используйте их как отправную точку для автоматизации рутины и сосредоточьтесь на бизнес-логике. Экспериментируйте, адаптируйте под свои проекты и не забывайте про тесты. Если вы хотите углубиться в тему, рекомендую изучить документацию Pinia и Composition API — это база, которая останется актуальной ещё долгие годы.
Комментарии