25. Nuxt 4: новые возможности
🆕 Nuxt 4 — Новые возможности
Заголовок раздела «🆕 Nuxt 4 — Новые возможности»Nuxt 4 — следующее поколение фреймворка с улучшенной структурой проекта, лучшей производительностью и упрощённой миграцией. Многие возможности уже доступны в Nuxt 3.x через экспериментальные флаги.
📁 Новая структура директорий (app/ directory)
Заголовок раздела «📁 Новая структура директорий (app/ directory)»Главное изменение Nuxt 4 — введение директории app/ для хранения кода приложения:
Nuxt 3 (текущая структура)
Заголовок раздела «Nuxt 3 (текущая структура)»my-nuxt3-app/├── assets/├── components/├── composables/├── layouts/├── middleware/├── pages/├── plugins/├── public/├── server/├── stores/├── utils/├── app.vue├── error.vue└── nuxt.config.tsNuxt 4 (новая структура)
Заголовок раздела «Nuxt 4 (новая структура)»my-nuxt4-app/├── app/ # ← ВСЁ приложение теперь здесь│ ├── assets/│ ├── components/│ ├── composables/│ ├── layouts/│ ├── middleware/│ ├── pages/│ ├── plugins/│ ├── stores/│ ├── utils/│ ├── app.vue│ └── error.vue├── public/ # статика (остаётся в корне)├── server/ # серверный код (остаётся в корне)└── nuxt.config.ts # конфигурация (остаётся в корне)🔄 Тестирование новой структуры в Nuxt 3
Заголовок раздела «🔄 Тестирование новой структуры в Nuxt 3»Активируйте Nuxt 4 совместимость уже сейчас:
export default defineNuxtConfig({ future: { compatibilityVersion: 4 }})После этого Nuxt будет искать файлы сначала в app/, затем в корне проекта.
🆕 Ключевые изменения Nuxt 4
Заголовок раздела «🆕 Ключевые изменения Nuxt 4»1. Улучшенный useAsyncData
Заголовок раздела «1. Улучшенный useAsyncData»// Nuxt 3 — данные не обновляются при смене параметров маршрутаconst { data } = await useAsyncData('user', () => fetchUser(route.params.id))
// Nuxt 4 — автоматическое отслеживание зависимостейconst { data } = await useAsyncData(() => fetchUser(route.params.id) // ключ генерируется автоматически // автоматически перезапускается при изменении route.params.id)2. Shared Prerender Data
Заголовок раздела «2. Shared Prerender Data»// Данные теперь деится между страницами при prerender// Один запрос к /api/config для всех 1000 страницconst { data: config } = await useAsyncData('config', () => $fetch('/api/config'), { server: true })3. Новый router.options.ts
Заголовок раздела «3. Новый router.options.ts»// app/router.options.ts (раньше app/router.options.ts уже существовал)import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig>{ scrollBehavior(to, from, savedPosition) { if (savedPosition) return savedPosition if (to.hash) return { el: to.hash, behavior: 'smooth' } return { top: 0 } }}🚀 Новые экспериментальные функции (Nuxt 3.x → 4)
Заголовок раздела «🚀 Новые экспериментальные функции (Nuxt 3.x → 4)»typedPages
Заголовок раздела «typedPages»export default defineNuxtConfig({ experimental: { typedPages: true }})// Типизированная навигацияconst router = useRouter()router.push({ name: 'blog-slug', params: { slug: 'my-post' } })// TypeScript знает о структуре params!viewTransition
Заголовок раздела «viewTransition»export default defineNuxtConfig({ experimental: { viewTransition: true }})<template> <!-- View Transitions API для плавной навигации --> <NuxtLink :to="post.path" :view-transition-name="post.id"> {{ post.title }} </NuxtLink></template>Nuxt Scripts (новый модуль)
Заголовок раздела «Nuxt Scripts (новый модуль)»// Оптимизированная загрузка внешних скриптовexport default defineNuxtConfig({ modules: ['@nuxt/scripts'], scripts: { registry: { googleAnalytics: true, fathomAnalytics: true, stripe: true } }})<script setup>const { $script } = useScriptGoogleAnalytics({ id: 'G-XXXXXXXXXX'})</script>🔧 Улучшения производительности
Заголовок раздела «🔧 Улучшения производительности»Granular Loading States
Заголовок раздела «Granular Loading States»<!-- Nuxt 4: более гранулярный контроль --><script setup>const { data, status } = await useAsyncData('data', fetchData)// status: 'idle' | 'pending' | 'success' | 'error'</script>
<template> <div v-if="status === 'pending'">Загрузка...</div> <div v-else-if="status === 'error'">Ошибка</div> <div v-else>{{ data }}</div></template>Улучшенный tree-shaking
Заголовок раздела «Улучшенный tree-shaking»// Nuxt 4 автоматически удаляет неиспользуемые части// Vue Router, Pinia и другие пакеты tree-shaken агрессивнееexport default defineNuxtConfig({ optimization: { keyedComposables: true }})📦 Новые встроенные возможности
Заголовок раздела «📦 Новые встроенные возможности»useRequestHeader
Заголовок раздела «useRequestHeader»// Nuxt 4 — улучшенный доступ к заголовкамconst xForwardedFor = useRequestHeader('x-forwarded-for')const userAgent = useRequestHeader('user-agent')useResponseHeader
Заголовок раздела «useResponseHeader»// Установка заголовков ответаconst setHeader = useResponseHeader()setHeader('X-Custom-Header', 'value')Улучшенный useSeoMeta
Заголовок раздела «Улучшенный useSeoMeta»// Nuxt 4 — расширенные SEO возможностиuseSeoMeta({ title: 'Заголовок страницы', ogTitle: 'Заголовок для OG', description: 'Описание страницы', ogDescription: 'OG описание', ogImage: 'https://example.com/og.jpg', twitterCard: 'summary_large_image', twitterTitle: 'Twitter заголовок', // Новые в v4: articlePublishedTime: new Date().toISOString(), articleAuthor: ['Александр']})🗺️ Руководство по миграции
Заголовок раздела «🗺️ Руководство по миграции»Шаг 1: Обновление Nuxt
Заголовок раздела «Шаг 1: Обновление Nuxt»npx nuxi upgrade --forceШаг 2: Включение Nuxt 4 совместимости
Заголовок раздела «Шаг 2: Включение Nuxt 4 совместимости»export default defineNuxtConfig({ future: { compatibilityVersion: 4 }})Шаг 3: Перенос файлов в app/
Заголовок раздела «Шаг 3: Перенос файлов в app/»mkdir app
# Переместить файлы приложенияmv assets app/mv components app/mv composables app/mv layouts app/mv middleware app/mv pages app/mv plugins app/mv stores app/mv utils app/mv app.vue app/mv error.vue app/Шаг 4: Обновление useAsyncData
Заголовок раздела «Шаг 4: Обновление useAsyncData»// Было (Nuxt 3)const { data } = await useAsyncData( 'user-' + userId, () => fetchUser(userId))
// Стало (Nuxt 4 рекомендованный стиль)const { data } = await useAsyncData( () => fetchUser(userId) // ключ генерируется автоматически из функции)Шаг 5: Проверка путей
Заголовок раздела «Шаг 5: Проверка путей»// Убедитесь что алиасы работают// ~ и @ теперь указывают на app/ директориюimport MyComponent from '~/components/MyComponent.vue'// Nuxt автоматически резолвит к app/components/📊 Что изменилось: сравнение
Заголовок раздела «📊 Что изменилось: сравнение»| Аспект | Nuxt 3 | Nuxt 4 |
|---|---|---|
| Структура | Файлы в корне | Файлы в app/ |
| useAsyncData ключ | Обязательный | Автогенерация |
| View Transitions | Экспериментально | Стабильно |
| Typed Pages | Экспериментально | Стабильно |
| Shared Prerender | Нет | Есть |
| Scripts Module | Отдельно | Встроено |
| Compatibility | — | compatibilityVersion: 4 |
⚡ Когда выйдет Nuxt 4?
Заголовок раздела «⚡ Когда выйдет Nuxt 4?»По дорожной карте:
- Nuxt 3.x — новые функции добавляются через
future.*флаги - Nuxt 4 — стабильный релиз после завершения экспериментального периода
- Миграция — максимально неломающая (breaking changes минимальны)
// Начинайте тестировать уже сейчас:export default defineNuxtConfig({ future: { compatibilityVersion: 4 }, // Включить все Nuxt 4 поведения: experimental: { typedPages: true, viewTransition: true, payloadExtraction: true }})