layouts (макеты)

Nuxt предоставляет систему лейаутов для вынесения общей разметки в переиспользуемые шаблоны.
Компоненты из этой директории при использовании подгружаются асинхронно для лучшей производительности.

Включение лейаутов

Лейауты включаются добавлением <NuxtLayout> в app.vue:

app/app.vue
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

Чтобы задать лейаут:

  • Укажите свойство layout на странице через definePageMeta.
  • Задайте проп name у <NuxtLayout>.
  • Либо свойство appLayout в route rules.
Имя лейаута приводится к kebab-case: someLayoutsome-layout.
Если лейаут не указан, используется app/layouts/default.vue.
Если в приложении один лейаут, лучше обойтись без директории layouts и задать разметку в app.vue.
В отличие от остальных компонентов, у лейаутов должен быть один корневой элемент (и не <slot />), чтобы Nuxt мог применять переходы при смене лейаута.

Лейаут по умолчанию

Добавьте ~/layouts/default.vue:

app/layouts/default.vue
<template>
  <div>
    <p>Общая разметка для всех страниц</p>
    <slot />
  </div>
</template>

Содержимое страницы выводится в компоненте <slot />.

Именованный лейаут

Структура каталогов
-| layouts/
---| default.vue
---| custom.vue

Использование лейаута custom на странице:

pages/about.vue
<script setup lang="ts">
declare module 'nuxt/app' {
  interface NuxtLayouts {
    'custom': unknown
  }
}
// ---cut---
definePageMeta({
  layout: 'custom',
})
</script>
Подробнее о definePageMeta.

Лейаут по умолчанию для всех страниц можно переопределить пропом name у <NuxtLayout>:

app/app.vue
<script setup lang="ts">
// Например, в зависимости от API или статуса авторизации
const layout = 'custom'
</script>

<template>
  <NuxtLayout :name="layout">
    <NuxtPage />
  </NuxtLayout>
</template>

Для лейаутов во вложенных папках имя строится из пути и имени файла, повторяющиеся сегменты убираются.

ФайлИмя лейаута
~/layouts/desktop/default.vuedesktop-default
~/layouts/desktop-base/base.vuedesktop-base
~/layouts/desktop/index.vuedesktop

Рекомендуется, чтобы имя файла совпадало с именем лейаута:

ФайлИмя лейаута
~/layouts/desktop/DesktopDefault.vuedesktop-default
~/layouts/desktop-base/DesktopBase.vuedesktop-base
~/layouts/desktop/Desktop.vuedesktop
Прочитайте и отредактируйте живой пример в Docs > 4 X > Examples > Features > Layouts.

Смена лейаута во время работы

Используйте хелпер setPageLayout:

<script setup lang="ts">
declare module 'nuxt/app' {
  interface NuxtLayouts {
    'custom': unknown
  }
}
// ---cut---
function enableCustomLayout () {
  setPageLayout('custom')
}
definePageMeta({
  layout: false,
})
</script>

<template>
  <div>
    <button @click="enableCustomLayout">
      Сменить лейаут
    </button>
  </div>
</template>

Лейаут для конкретных маршрутов можно задать через свойство appLayout в route rules:

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // Лейаут для маршрута
    '/admin': { appLayout: 'admin' },
    // Лейаут для нескольких маршрутов
    '/dashboard/**': { appLayout: 'dashboard' },
    // Отключить лейаут для маршрута
    '/landing': { appLayout: false },
  },
})
Удобно, когда лейауты задаются в конфиге, а не в каждом файле страницы, или когда нужно применить лейаут к маршрутам без страниц (например, catch-all).
Прочитайте и отредактируйте живой пример в Docs > 4 X > Examples > Features > Layouts.

Переопределение лейаута на странице

При использовании страниц можно отключить лейаут через layout: false и использовать <NuxtLayout> прямо на странице.

<script setup lang="ts">
definePageMeta({
  layout: false,
})
</script>

<template>
  <div>
    <NuxtLayout name="custom">
      <template #header>
        Содержимое шапки.
      </template>

      Остальное содержимое страницы
    </NuxtLayout>
  </div>
</template>
Если <NuxtLayout> используется внутри страницы, он не должен быть корневым элементом (или отключите переходы для лейаута/страницы).