5. Nuxt 3 布局
5.1 布局概念
布局(Layouts)是 Nuxt 应用程序中的一个包装组件,可用于在多个页面之间共享通用的 UI 结构。布局通常用于放置导航栏、页脚等在多个页面中重复出现的元素。
在 Nuxt 3 中,布局文件需要放置在 layouts
目录下。
5.2 定义布局
5.2.1 默认布局
默认布局文件为 layouts/default.vue
,它将自动应用到所有页面:
vue
<script setup lang="ts">
interface HeaderProps {
title: string
}
const props = withDefaults(defineProps<HeaderProps>(), {
title: '默认标题'
})
</script>
<template>
<div>
<header>
<nav>
<h1>{{ props.title }}</h1>
</nav>
</header>
<main>
<slot />
</main>
<footer>
<!-- 页脚内容 -->
</footer>
</div>
</template>
5.2.2 自定义布局
你可以创建多个布局文件,例如 layouts/custom.vue
:
vue
<script setup lang="ts">
interface AsideMenu {
id: number
title: string
path: string
}
const menuItems = ref<AsideMenu[]>([
{ id: 1, title: '菜单1', path: '/menu1' },
{ id: 2, title: '菜单2', path: '/menu2' }
])
</script>
<template>
<div class="custom-layout">
<aside>
<template v-for="item in menuItems" :key="item.id">
<NuxtLink :to="item.path">{{ item.title }}</NuxtLink>
</template>
</aside>
<div class="content">
<slot />
</div>
</div>
</template>
5.3 使用布局
5.3.1 在页面中使用布局
可以通过以下方式在页面中使用特定布局:
vue
<script setup>
definePageMeta({
layout: 'custom'
})
</script>
<template>
<div>
<!-- 页面内容 -->
</div>
</template>
5.3.2 动态切换布局
你可以根据条件动态切换布局:
vue
<script setup lang="ts">
type LayoutType = 'default' | 'custom'
const layout = ref<LayoutType>('default')
const changeLayout = (): void => {
layout.value = layout.value === 'default' ? 'custom' : 'default'
}
</script>
<template>
<div>
<button @click="changeLayout">切换布局</button>
<!-- 页面内容 -->
</div>
</template>
5.4 布局示例
5.4.1 管理后台布局
vue
<script setup lang="ts">
interface MenuItem {
id: number
title: string
path: string
icon?: string
}
interface UserInfo {
name: string
avatar: string
role: string
}
const menuItems = ref<MenuItem[]>([
{ id: 1, title: '仪表盘', path: '/admin/dashboard', icon: 'dashboard' },
{ id: 2, title: '用户管理', path: '/admin/users', icon: 'users' },
{ id: 3, title: '系统设置', path: '/admin/settings', icon: 'settings' }
])
const userInfo = ref<UserInfo>({
name: '管理员',
avatar: '/avatar.png',
role: 'admin'
})
</script>
<template>
<div class="admin-layout">
<nav class="sidebar">
<template v-for="item in menuItems" :key="item.id">
<NuxtLink :to="item.path">
<i v-if="item.icon" :class="item.icon" />
{{ item.title }}
</NuxtLink>
</template>
</nav>
<div class="main-content">
<header>
<h1>管理后台</h1>
<div class="user-info">
<img :src="userInfo.avatar" :alt="userInfo.name">
<span>{{ userInfo.name }}</span>
</div>
</header>
<main>
<slot />
</main>
</div>
</div>
</template>
<style scoped>
.admin-layout {
display: grid;
grid-template-columns: 250px 1fr;
min-height: 100vh;
}
.sidebar {
background-color: #f4f4f4;
padding: 1rem;
}
.main-content {
padding: 1rem;
}
</style>
5.5 最佳实践
- 为不同类型的页面创建专门的布局
- 使用 CSS Grid 或 Flexbox 构建灵活的布局结构
- 考虑响应式设计,适配不同设备
- 合理使用插槽分发内容
- 保持布局组件的单一职责
5.6 注意事项
- 布局文件必须包含
<slot />
组件以显示页面内容 - 布局切换时会触发组件重新渲染
- 避免在布局中放置过多的业务逻辑
- 建议使用 CSS Grid 或 Flexbox 构建布局结构
5.7 小结
Nuxt 3 的布局系统提供了一种优雅的方式来组织和复用页面结构。通过合理使用布局,可以显著提高开发效率和代码复用率。