Nuxt4 布局系统
布局(Layout)是页面的”外壳”,用于包裹页面内容,网站常见的 Header、Footer、侧边栏都是公共部分,如果每个页面都复制一遍就太傻了,布局系统就是解决这个问题的。
基本概念
想象一个网站,所有页面顶部都有导航栏,底部都有版权信息。用布局系统,你只需要写一次导航栏和版权信息,所有页面自动套上这个外壳。
+-------------------------+
| Header 导航栏(写一次) |
+-------------------------+
| |
| 页面内容(各不相同) |
| |
+-------------------------+
| Footer 版权信息(写一次)|
+-------------------------+
默认布局
在 app/layouts/ 目录下创建 default.vue,这就是默认布局,所有页面自动使用:
<template>
<div>
<header>
<nav>
<NuxtLink to="/">首页</NuxtLink>
<NuxtLink to="/about">关于</NuxtLink>
</nav>
</header>
<!-- 页面内容渲染在 <slot /> 位置 -->
<main>
<slot />
</main>
<footer>
<p>版权所有</p>
</footer>
</div>
</template>
关键点在于 <slot />,页面内容会填充到这里。
开启布局
布局需要配合 app/app.vue 使用。修改 app/app.vue:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<NuxtPage />渲染当前页面<NuxtLayout>把页面内容包进布局中,页面内容会填充到布局的<slot />位置
没有 <NuxtLayout> 的话,布局不会生效,页面会直接渲染。
自定义布局
某些页面需要不同的外壳,比如登录页不想要导航栏,后台管理页想要侧边栏。
在 app/layouts/ 下再创建一个 custom.vue,比如一个全屏无导航的布局:
<template>
<div class="fullscreen">
<slot />
</div>
</template>
然后在页面中用 definePageMeta 指定使用哪个布局:
<!-- app/pages/login.vue -->
<script setup>
definePageMeta({
layout: 'custom'
})
</script>
<template>
<div>
<h1>登录页</h1>
<p>这个页面没有导航栏</p>
</div>
</template>
布局名称对应文件名,app/layouts/custom.vue 就用 layout: 'custom',文件名是驼峰式(如 errorLayout.vue)时,布局名要写成连字符形式(error-layout)。
禁用布局
layout: false 可以完全禁用布局:
<script setup>
definePageMeta({
layout: false
})
</script>
布局速查表
| 需求 | 做法 |
|---|---|
| 所有页面用同一外壳 | 创建 app/layouts/default.vue |
| 某页面用不同外壳 | 创建布局文件,页面里 definePageMeta({ layout: 'xxx' }) |
| 页面不要外壳 | definePageMeta({ layout: false }) |
| 布局不生效 | 检查 app.vue 是否包了 <NuxtLayout> |
一句话总结:布局就是页面外壳,在 app/layouts/ 建文件,页面用 definePageMeta 选壳,内容渲染在布局的 <slot /> 里。