layouts
Nuxt 提供布局框架,将常见的 UI 模式提取到可重用的布局中。
为了获得最佳性能,放置在此目录中的组件将在使用时通过异步导入自动加载。
启用布局
通过将 <NuxtLayout> 添加到你的 app.vue 来启用布局:
app/app.vue
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
要使用布局:
- 在你的页面中使用 definePageMeta 设置
layout属性。 - 设置
<NuxtLayout>的nameprop。 - 在路由规则中设置
appLayout属性。
布局名称规范化为 kebab-case,因此
someLayout 变为 some-layout。如果未指定布局,将使用
app/layouts/default.vue。如果你的应用程序中只有一个布局,我们建议使用
app.vue 代替。与其他组件不同,你的布局必须具有单个根元素,以便 Nuxt 在布局更改之间应用转换 - 并且此根元素不能是
<slot />。默认布局
添加 ~/layouts/default.vue:
app/layouts/default.vue
<template>
<div>
<p>Some default layout content shared across all pages</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>
你可以使用 <NuxtLayout> 的 name 属性直接覆盖所有页面的默认布局:
app/app.vue
<script setup lang="ts">
// 你可能基于 API 调用或登录状态选择此项
const layout = 'custom'
</script>
<template>
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>
如果你在嵌套目录中有布局,布局的名称将基于其自己的路径目录和文件名,删除重复的段。
| 文件 | 布局名称 |
|---|---|
~/layouts/desktop/default.vue | desktop-default |
~/layouts/desktop-base/base.vue | desktop-base |
~/layouts/desktop/index.vue | desktop |
为了清晰起见,我们建议布局的文件名与其名称匹配:
| 文件 | 布局名称 |
|---|---|
~/layouts/desktop/DesktopDefault.vue | desktop-default |
~/layouts/desktop-base/DesktopBase.vue | desktop-base |
~/layouts/desktop/Desktop.vue | desktop |
在 Docs > 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">
Update layout
</button>
</div>
</template>
你也可以使用路由规则中的 appLayout 属性为特定路由设置布局:
nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// 为特定路由设置布局
'/admin': { appLayout: 'admin' },
// 为多个路由设置布局
'/dashboard/**': { appLayout: 'dashboard' },
// 禁用路由的布局
'/landing': { appLayout: false },
},
})
这在你希望集中管理配置中的布局而不是在每个页面文件中管理布局时,或者当你需要将布局应用于没有相应页面组件的路由(例如,可能匹配许多路径的 catchall 页面)时非常有用。
在 Docs > Examples > Features > Layouts 中阅读和编辑实时示例。
按页面覆盖布局
如果你使用页面,你可以通过设置 layout: false 然后在页面中使用 <NuxtLayout> 组件来完全控制。
<script setup lang="ts">
definePageMeta({
layout: false,
})
</script>
<template>
<div>
<NuxtLayout name="custom">
<template #header>
Some header template content.
</template>
The rest of the page
</NuxtLayout>
</div>
</template>
<template>
<div>
<header>
<slot name="header">
Default header content
</slot>
</header>
<main>
<slot />
</main>
</div>
</template>
如果你在页面中使用
<NuxtLayout>,请确保它不是根元素。