Nuxt.js фреймворк

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

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

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

Стандартная структура Nuxt-проекта включает несколько ключевых директорий:

  • pages/ — директория для страниц. Каждая .vue-страница автоматически становится маршрутом. Поддиректории создают вложенные маршруты.
  • components/ — компоненты интерфейса, используемые на страницах.
  • layouts/ — шаблоны страниц. Позволяет создавать единый каркас для нескольких страниц, например, с общим хедером и футером.
  • store/ — Vuex хранилище состояния приложения. Nuxt автоматически подключает его.
  • plugins/ — подключение сторонних библиотек и кастомных функций перед инициализацией приложения.
  • middleware/ — функции, выполняемые перед рендерингом страницы, например, проверка аутентификации.
  • nuxt.config.js — основной конфигурационный файл, где задаются маршруты, плагины, модули и глобальные настройки приложения.

Автоматическая маршрутизация

Nuxt автоматически генерирует маршруты на основе файлов в pages/. Например:

pages/
 ├─ index.vue       → /
 ├─ about.vue       → /about
 └─ blog/
     └─ _id.vue     → /blog/:id

Файл с подчеркиванием (_id.vue) используется для динамических маршрутов.

Серверный рендеринг (SSR)

SSR позволяет генерировать HTML на сервере, что улучшает SEO и ускоряет загрузку страницы. Nuxt поддерживает SSR «из коробки». Для этого достаточно запускать приложение в режиме nuxt start после сборки nuxt build.

В SSR приложение проходит через следующие этапы:

  1. Сервер получает HTTP-запрос.
  2. Nuxt рендерит Vue-компоненты на сервере в HTML.
  3. Браузер получает готовый HTML с подключенными JS-скриптами.
  4. Vue гидратирует страницы, делая их полностью интерактивными.

Для компонентов, данные которых нужно получать до рендеринга, используется хук asyncData:

export default {
  async asyncData({ params, $axios }) {
    const data = await $axios.$get(`/api/posts/${params.id}`);
    return { post: data };
  }
}

asyncData вызывается до инициализации компонента, поэтому данные будут сразу доступны при рендеринге страницы.

Статическая генерация (SSG)

Nuxt может генерировать статические сайты с помощью команды nuxt generate. Каждая страница превращается в HTML-файл, который можно разместить на CDN.

Пример конфигурации:

export default {
  target: 'static',
  generate: {
    routes: ['/about', '/contact']
  }
}

Работа с Vuex в Nuxt

Nuxt упрощает работу с хранилищем Vuex. Достаточно создать файл store/index.js:

export const state = () => ({
  counter: 0
});

export const mutations = {
  increment(state) {
    state.counter++;
  }
};

export const actions = {
  async fetchCounter({ commit }) {
    const value = await fetch('/api/counter').then(res => res.json());
    commit('setCounter', value);
  }
};

Nuxt автоматически подключает Vuex, если есть хотя бы один файл в store/.

Плагины и модули

Плагины используются для интеграции сторонних библиотек. Например:

// plugins/axios.js
import Vue from 'vue';
import axios from 'axios';

Vue.prototype.$axios = axios;

Подключение в nuxt.config.js:

export default {
  plugins: ['~/plugins/axios.js']
}

Модули Nuxt — это расширения, добавляющие функциональность, например, @nuxtjs/axios, @nuxtjs/auth-next, @nuxt/content. Они подключаются через modules в конфиге и упрощают интеграцию с внешними сервисами.

Middleware и навигационные гварды

Middleware выполняются перед рендерингом страницы. Они полезны для проверки прав доступа или перенаправления.

// middleware/auth.js
export default function ({ store, redirect }) {
  if (!store.state.user) {
    return redirect('/login');
  }
}

Применение на уровне страницы:

export default {
  middleware: 'auth'
}

Методы жизненного цикла страниц

Nuxt расширяет стандартные хуки Vue следующими методами:

  • asyncData — получение данных до рендеринга страницы.
  • fetch — получение данных после рендеринга компонента, но до отображения.
  • head — настройка метатегов страницы через vue-meta.

Пример настройки head:

export default {
  head() {
    return {
      title: 'Страница блога',
      meta: [
        { hid: 'description', name: 'description', content: 'Описание страницы' }
      ]
    }
  }
}

Настройка маршрутов и динамические страницы

Nuxt поддерживает динамические маршруты и вложенные страницы. Для динамических маршрутов используется синтаксис _param.vue.

Пример:

pages/
 └─ products/
     └─ _id.vue   → /products/:id

В компоненте доступ к параметру через params.id.

Вложенные маршруты создаются через папки и index.vue в них:

pages/
 └─ dashboard/
     ├─ index.vue   → /dashboard
     └─ settings.vue → /dashboard/settings

Работа с формами и компонентами

Компоненты в Nuxt создаются стандартно, но их удобнее использовать через глобальное подключение или lazy-loading.

Пример глобального подключения:

// components/BaseButton.vue
<template>
  <button><slot/></button>
</template>

<script>
export default {
  name: 'BaseButton'
}
</script>

Импорт через плагин:

// plugins/global-components.js
import Vue from 'vue';
import BaseButton from '~/components/BaseButton.vue';

Vue.component('BaseButton', BaseButton);

Выводы по использованию Nuxt.js

Nuxt.js значительно упрощает разработку на Vue, предлагая автоматическую маршрутизацию, SSR, SSG, удобную работу с Vuex и глобальные плагины. Структура проекта, хуки жизненного цикла страниц и поддержка middleware делают фреймворк гибким для больших приложений.

Каждый проект на Nuxt начинается с четкой организации директорий и конфигурации nuxt.config.js, что позволяет сразу применять SSR или SSG, подключать плагины и управлять маршрутизацией без ручного создания роутеров и сложной серверной логики.