layouts

Каталог layouts/ — общие каркасы интерфейса в виде переиспользуемых лейаутов.
Компоненты из этого каталога подгружаются лениво, когда лейаут реально используется.

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

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

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

Чтобы использовать лейаут:

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

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

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

layouts/default.vue
<template>
  <div>
    <p>Некоторый контент лейаута по умолчанию, общий для всех страниц</p>
    <slot />
  </div>
</template>

В файле лейаута содержимое страницы будет отображаться в компоненте <slot />.

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

Directory Structure
-| 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.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 > 3 X > Examples > Features > Layouts.

Динамическое изменение лейаута

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

app/pages/index.vue
<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 в правилах маршрутов:

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // Лейаут для конкретного маршрута
    '/admin': { appLayout: 'admin' },
    // Лейаут для нескольких маршрутов
    '/dashboard/**': { appLayout: 'dashboard' },
    // Отключить лейаут для маршрута
    '/landing': { appLayout: false },
  },
})
Это удобно, когда лейауты задаются централизованно в конфигурации, а не в каждом файле страницы, или когда нужно применить лейаут к маршрутам без отдельных компонентов страниц (например, catch-all, совпадающим со многими путями).
Прочитайте и отредактируйте живой пример в Docs > 3 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> на своих страницах, убедитесь, что он не является корневым элементом (или отключите лейаут/переходы страниц).