логотип PurpleSchool
логотип PurpleSchool

Пошаговая инструкция по интеграции Vue и Nuxt

Автор

Олег Марков

Введение

Vue — это современный JavaScript-фреймворк для создания пользовательских интерфейсов, легкий в освоении и гибкий в работе. Однако, если вы хотите использовать серверный рендеринг (SSR), маршрутизацию из коробки, автоматическую генерацию страниц и удобные практики разработки, то стоит познакомиться с Nuxt. Nuxt — это метафреймворк на базе Vue, который помогает строить масштабируемые приложения на Vue быстрее и проще.

В этой пошаговой инструкции я покажу вам, как интегрировать Vue-проекты или отдельные Vue-компоненты в Nuxt. Мы разберем архитектурные особенности, объясним нюансы работы с файлами и компонентами, а также подготовим базовое приложение Nuxt с использованием компонентов Vue. Все шаги иллюстрируются примерами кода, которые помогут вам разобраться в деталях интеграции.

Установка и инициализация Nuxt-проекта

Почему стартовать с Nuxt важно для интеграции

Nuxt берет на себя много рутинной работы: настройка SSR, маршрутизация, работа с meta-тегами, структуры директорий. Если у вас есть Vue-компоненты или мини-приложения, их проще всего интегрировать именно в проект, инициализированный Nuxt.

Подготовка рабочего окружения

Перед началом убедитесь, что у вас установлен Node.js (желательно версия 16 и выше). Проверьте это командой:

node -v

Если у вас нет Node.js, скачайте его с официального сайта nodejs.org.

Установка Nuxt 3 с помощью npx

Nuxt 3 сейчас является актуальной версией и рекомендуется для новых проектов. Переходим к инициализации проекта:

npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install
  • nuxi — CLI инструмент для работы с Nuxt 3.
  • my-nuxt-app — директория вашего нового проекта.

После установки вы можете стартовать локальный сервер:

npm run dev

Посетите http://localhost:3000 и убедитесь, что видите приветственную страницу Nuxt.

Структура Nuxt-проекта

Так выглядит базовая структура нового проекта:

my-nuxt-app/
|-- assets/
|-- components/
|-- layouts/
|-- pages/
|-- public/
|-- nuxt.config.ts
  • components/ — здесь будут располагаться Vue-компоненты.
  • pages/ — Nuxt автоматически создает маршруты на основе файлов в этой папке.

Интеграция Vue-компонентов в Nuxt-проект

Подходы к интеграции

Давайте рассмотрим два основных сценария:

  1. У вас есть готовый Vue-компонент (или небольшая библиотека), и вы хотите использовать его в Nuxt.
  2. Вы постепенно мигрируете существующее SPA на Vue к приложению на Nuxt.

Добавление собственного Vue-компонента

Допустим, у вас есть следующий компонент (MyButton.vue):

<template>
  <button @click="handleClick">
    <slot></slot>
  </button>
</template>

<script setup>
// Поведение кнопки реализовано через props и методы
const handleClick = () => {
  alert('Вы нажали кнопку!')
}
</script>

Теперь скопируйте этот компонент в папку components/ вашего Nuxt-проекта.

Интеграция Vue и Nuxt может значительно расширить возможности вашего проекта, позволяя использовать преимущества обоих фреймворков. Но чтобы интеграция прошла гладко и эффективно, необходимо четкое понимание архитектуры и особенностей каждого из них. Если вы хотите детальнее погрузиться в мир Nuxt, освоить все его тонкости и стать настоящим профессионалом — приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Использование компонента в Nuxt-странице

Nuxt автоматически регистрирует все компоненты в папке components/. Просто используйте компонент в любом шаблоне страницы (например, в pages/index.vue):

<template>
  <div>
    <MyButton>Привет из компонента!</MyButton>
  </div>
</template>
  • Обратите внимание: импортировать компонент вручную не нужно, Nuxt 3 сам найдет MyButton.vue.

Интеграция сторонних Vue-компонентов

Если вам нужно использовать внешний плагин или библиотеку Vue-компонентов (например, Element Plus), поставьте её как зависимость:

npm install element-plus

Далее подключите её в Nuxt через auto-import, плагин или на уровне конкретного компонента/страницы.

Покажу пример настройки Element Plus через плагин Nuxt:

  1. Создайте файл plugins/element-plus.js:
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.use(ElementPlus)
})
  1. Nuxt автоматически подключит все плагины из папки plugins/.

Теперь любой компонент Element Plus можно использовать в ваших шаблонах:

<template>
  <el-button>Нажмите меня</el-button>
</template>

Интеграция существующего SPA на Vue в Nuxt

Если у вас есть SPA на Vue 2/3, вы можете постепенно переносить её в структуру Nuxt:

  • Перенесите ваши компоненты в папку components/.
  • Логическую часть страниц перенесите в папку pages/ (каждый vue-файл в pages автоматически становится маршрутом).
  • Общие стили — в папку assets/.
  • Внешние скрипты и изображения — в public/.

При миграции со Vue 2 стоит учесть различия синтаксиса, так как Nuxt 3 полностью на Vue 3 и использует Composition API как предпочтительный способ организации логики.

Пример преобразования обычной страницы во Vue в Nuxt-страницу

Стандартная страница во Vue:

<template>
  <div>
    <h1>Мой профиль</h1>
  </div>
</template>
<script>
export default {
  name: "ProfilePage"
}
</script>

В Nuxt 3 эта страница просто размещается в pages/profile.vue, роутинг происходит автоматически:

<template>
  <div>
    <h1>Мой профиль в Nuxt</h1>
  </div>
</template>

Теперь можно перейти по адресу /profile на вашем сайте и увидеть новую страницу.

Работа с асинхронными данными и серверным рендерингом

Использование useFetch и useAsyncData

Nuxt 3 предоставляет интеграцию для загрузки данных как на сервере, так и на клиенте. Вам доступны хуки useFetch и useAsyncData.

Посмотрите пример получения данных на сервере:

<script setup>
const { data: posts, error } = await useFetch('https://jsonplaceholder.typicode.com/posts')
// posts теперь содержит результат fetch-запроса
</script>

<template>
  <div>
    <h2>Список постов</h2>
    <ul>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
    <div v-if="error">Ошибка загрузки данных</div>
  </div>
</template>
  • Преимущество: useFetch умеет работать и на стороне сервера, и после перехода между страницами.
  • На клиенте – данные не будут перезапрашиваться, если они уже были получены на сервере.

Как работают layouts, middleware и meta-информация

Layouts

В папке layouts/ вы можете создавать шаблоны, общие для групп страниц. Например, файл default.vue определяет базовый layout:

<template>
  <div>
    <header>Заголовок приложения</header>
    <slot></slot> <!-- Здесь отображается содержимое страницы -->
    <footer>©2024</footer>
  </div>
</template>

В каждой странице вы можете указать свой layout:

<script setup>
definePageMeta({
  layout: "default"
})
</script>

Middleware

Если нужны проверки авторизации или другие промежуточные функции при загрузке роутов, используйте middleware. Создайте файл, например, middleware/auth.js:

export default defineNuxtRouteMiddleware((to, from) => {
  // Проверка, что пользователь авторизован
  if (!useAuth().isLoggedIn) {
    return navigateTo('/login') // Редирект на страницу логина
  }
})

Подключите middleware в нужной странице:

<script setup>
definePageMeta({
  middleware: 'auth'
})
</script>

Работа с meta-тегами

Nuxt 3 позволяет удобно управлять мета-тегами страницы:

<script setup>
useHead({
  title: 'О нас - Мой сайт',
  meta: [
    { name: 'description', content: 'Информация о нашей компании' }
  ]
})
</script>

Интеграция Vuex или Pinia

С переходом на Nuxt 3, рекомендуется использовать Pinia для глобального состояния. Установка Pinia:

npm install pinia

Создайте файл плагина plugins/pinia.js:

import { createPinia } from 'pinia'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(createPinia())
})

Пример простого состояния в stores/counter.js:

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

В компоненте используйте так:

<script setup>
import { useCounterStore } from '~/stores/counter'
const counter = useCounterStore()
</script>

<template>
  <button @click="counter.increment">
    {{ counter.count }}
  </button>
</template>

Подключение собственных плагинов и глобальных функций

Если у вас в Vue были глобальные миксины, плагины или инъекции, в Nuxt их подключают как плагины — положите исходный JS-файл в папку plugins/, Nuxt подключит его автоматически.

Например, регистрируем глобальную функцию:

// plugins/global-func.js
export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.config.globalProperties.$sayHello = (name) => `Привет, ${name}!`
})

И используем её в компоненте:

<script setup>
const nuxtApp = useNuxtApp()
const message = nuxtApp.$sayHello('Анна')
</script>

<template>{{ message }}</template>

Организация и импорт стилей

Работайте со стилями как обычно во Vue:

  • Глобальные стили — в assets/main.css, подключается через nuxt.config.ts:
export default defineNuxtConfig({
  css: ['~/assets/main.css']
})
  • Стили, специфичные для компонента — в <style scoped> внутри .vue-файлов.

Использование composables

Nuxt поддерживает composables — функции-композиции для повторного использования логики. Создайте функцию в composables/useCounter.js:

export const useCounter = () => {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
}

Он сразу будет доступен в любом компоненте:

<script setup>
const { count, increment } = useCounter()
</script>

Интеграция с внешними API и SSR

Nuxt отлично работает как с REST, так и с GraphQL API. Все фетчинги, вынесенные в useFetch/useAsyncData, пройдут инициализацию на сервере, если страница зарендерена сервером — или на клиенте, если запрос происходит только при навигации. Это позволяет делать полноценные SEO-оптимизированные и быстрые приложения.

Заключение

Интеграция Vue-компонентов и всего стека функциональности Vue во фреймворк Nuxt — процесс логичный и предсказуемый. Вы опираетесь на автоматический импорт компонентов, файловую маршрутизацию, серверный рендеринг и плагинную архитектуру Nuxt. Проект становится более структурированным, а разработка — быстрой и гибкой за счет глубокой интеграции всех преимуществ экосистемы Vue.

Используйте плагины, composables, современную систему состояния и глобальные функции для расширения возможностей вашего приложения. Nuxt помогает выводить ваши проекты на новый уровень без избыточных настроек и рутинного кода.

Интеграция Vue и Nuxt требует не только технических навыков, но и глубокого понимания взаимодействия между компонентами, маршрутизацией и серверной частью. Чтобы успешно интегрировать Vue в Nuxt и избежать распространенных ошибок, необходима практика и наставничество. На курсе Nuxt - fullstack Vue фреймворк вы научитесь создавать сложные веб-приложения, интегрируя Vue компоненты в Nuxt проект. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир Nuxt прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как подключить сторонние библиотеки, которые используют только Vue 2, к проекту на Nuxt 3 (Vue 3)?

Ответ: Nuxt 3 не поддерживает плагины, написанные для Vue 2, без адаптации. Некоторые библиотеки уже портированы на Vue 3. Если нужной версии нет — ищите альтернативу или портируйте вручную (потребуется изменить API с использованием Composition API и заменить deprecated-методы).

Как можно сделать глобальные переменные и использовать их в любом компоненте Nuxt?

Ответ: Создайте плагин в папке plugins/, экспортируйте в нем глобальные переменные через provide или с помощью nuxtApp.vueApp.config.globalProperties. Внутри компонента используйте useNuxtApp для доступа.

Почему мой компонент не отображается при размещении его в components/?

Ответ: Проверьте, совпадает ли имя файла и тега (например, MyButton.vue и <MyButton>), нет ли опечаток, и находится ли файл именно в папке components, а не вложенной подпапке (для вложенных — используйте PascalCase: <ButtonMy> для Button/My.vue).

Как добавить собственный favicon или изображения для статических ресурсов?

Ответ: Положите нужные файлы в папку public/ вашего Nuxt проекта (например, public/favicon.ico). Nuxt сервирует их на корневом уровне: https://your-site.com/favicon.ico.

Что делать если SSR ломается из-за использования window или document в компоненте?

Ответ: Используйте проверки на наличие сервера/клиента через хуки, например:
js if (process.client) { // Здесь безопасно использовать window/document } Или используйте onMounted, который вызывается только на клиенте.

Использование scripts в NuxtСтрелочка вправо

Постройте личный план изучения Nuxt до уровня Middle — бесплатно!

Nuxt — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtГенерация статического сайта с помощью NuxtРуководство по получению данных с Fetch в NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак запустить Nuxt-приложение в productionКак работает Server-Side Rendering SSR в NuxtНастройка и оптимизация серверной части Nuxt-приложенияРуководство по настройке маршрутизации в NuxtКакие проекты разумно реализовывать на NuxtИнструкция по управлению пакетами NPM в NuxtИнтеграция Node.js для Nuxt-приложенияНастройка мета-тегов для SEO в NuxtНастройка и использование HTTPS в NuxtКак отлавливать и обрабатывать ошибки в NuxtКак развернуть Nuxt приложение в DockerРуководство по развертыванию приложений в Nuxt CloudКак оптимизировать сборку на NuxtИнтеграция Laravel и Nuxt
Открыть базу знаний

Лучшие курсы по теме

Иконка ракетыСкоро!
изображение курса

Nuxt

Антон Ларичев
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий