Skip to content
快速导航

Layouts - 布局目录

Nuxt提供了一个可定制的布局框架,可以在整个应用程序中使用,是提取常见的 UI 或代码模式为可重用的布局组件的理想选择。

布局被放置在layouts目录下,使用时将通过异步导入自动加载。布局的使用方法是将<NuxtLayout>添加到app.vue中,并将布局属性设置为页面元数据的一部分(如果你使用~/pages集成),或者通过手动将其指定为<NuxtLayout>的一个prop。(注意:布局名称被规范化为kebab-case,所以someLayout变成了some-layout)。

如果你的应用程序中只有一个单一的布局,我们建议使用app.vue代替。

TIP

与其他组件不同,layout必须有一个单一的根元素,以允许 Nuxt 在布局变化之间应用过渡,这个根元素不能是一个<slot />

Default Layout

添加一个~/layouts/default.vue

<template>
  <div>
    所有页面共享一些默认布局
    <slot />
  </div>
</template>

在一个layout文件中,layout的内容将在<slot />中加载,而不是使用一个特殊的组件。

如果是使用app.vue,需要添加<NuxtLayout>

<template>
  <NuxtLayout>
    some page content
  </NuxtLayout>
</template>

自定义 Layout

-| layouts/
---| default.vue
---| custom.vue
  1. 直接覆盖默认布局,如下:

app.vue

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

<script setup>
// 根据需求来设置 layout
const layout = "custom";
</script>
  1. 设置不同的布局:

~/pages/index.vue

<script>
// 在`<script setup>`和`<script>`中都可以使用
definePageMeta({
  layout: "custom",
});
</script>

查看definePageMeta详细说明

~/app.vue

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

~/layouts/custom.vue应用到~/pages/index.vue

<template>
  <div>
    自定义布局
    <slot />
  </div>
</template>

~/layouts/default.vue:应用到app.vue

<template>
  <div>
    默认布局
    <slot />
  </div>
</template>

如上实现了app.vue~/pages/index.vue有各自有不同的布局方式

重写布局

如果使用~/pages集成,可以通过设置layout: false,然后~/pages页面中使用<NuxtLayout>组件结合slot来实现完全控制。

~/pages/index.vue

<template>
  <div> <!-- 这里必须有一个根元素 -->
    <NuxtLayout name="custom">
      <template #header> Some header template content. </template>

      The rest of the page
    </NuxtLayout>
  </div>
</template>

<script setup>
definePageMeta({
  layout: false, // 禁用 layout
});
</script>

~/layouts/custom.vue

<template>
  <div>
    <header>
      <slot name="header">
        Default header content
      </slot>
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>

TIP

如果页面中使用<NuxtLayout>,确保它不是根元素(或者禁用layout/page transitions)。

动态布局

布局中使用refcomputed属性:

<template>
  <div>
    <button @click="enableCustomLayout">Update layout</button>
  </div>
</template>

<script setup>
const route = useRoute()
function enableCustomLayout () {
  route.meta.layout = "custom"
}
definePageMeta({
  layout: false, // 需要设置组件选项 layout: false
});
</script>

阅读在线示例:https://v3.nuxtjs.org/examples/routing/layouts/