入门篇四:Nuxt4布局系统:让页面框架复用变得简单

目录

一、默认布局

二、自定义布局

三、动态切换布局

四、布局嵌套

五、布局中传递数据

六、命名插槽

总结


做网站时,你是不是经常遇到这种情况:首页、列表页、详情页都有相同的头部导航和底部版权信息。最笨的办法是每个页面都复制一遍,但改起来就痛苦了------改一个 footer 要改十个文件。Nuxt 的布局系统就是来解决这个问题的。

一、默认布局

布局文件放在 layouts 目录。创建一个默认布局:

复制代码
mkdir layouts

创建 layouts/default.vue

复制代码
<template>
  <div class="layout">
    <header class="header">
      <nav>
        <NuxtLink to="/">首页</NuxtLink>
        <NuxtLink to="/about">关于</NuxtLink>
        <NuxtLink to="/contact">联系</NuxtLink>
      </nav>
    </header>
    
    <main class="main">
      <slot />
    </main>
    
    <footer class="footer">
      <p>© 2024 我的网站. All rights reserved.</p>
    </footer>
  </div>
</template>

<style scoped>
.layout {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.header {
  background: #fff;
  border-bottom: 1px solid #eee;
  padding: 1rem;
}

.header nav a {
  margin-right: 1rem;
  color: #333;
  text-decoration: none;
}

.header nav a:hover {
  color: #00dc82;
}

.main {
  flex: 1;
  padding: 2rem;
}

.footer {
  background: #f5f5f5;
  padding: 1rem;
  text-align: center;
  color: #666;
}
</style>

然后页面中使用 <NuxtLayout> 包裹内容。但其实 Nuxt 已经自动帮你做了这件事,你只需要写页面内容:

pages/index.vue

复制代码
<template>
  <div>
    <h1>首页</h1>
    <p>欢迎来到我的网站</p>
  </div>
</template>

页面会自动应用 layouts/default.vue 布局,头部导航和底部版权自动出现。

二、自定义布局

有时候不同页面需要不同的布局。比如管理后台,没有头部导航,而是左侧菜单栏。

创建 layouts/admin.vue

复制代码
<template>
  <div class="admin-layout">
    <aside class="sidebar">
      <h3>管理后台</h3>
      <nav>
        <NuxtLink to="/admin/users">用户管理</NuxtLink>
        <NuxtLink to="/admin/articles">文章管理</NuxtLink>
        <NuxtLink to="/admin/settings">系统设置</NuxtLink>
      </nav>
    </aside>
    
    <main class="content">
      <slot />
    </main>
  </div>
</template>

<style scoped>
.admin-layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 200px;
  background: #2c3e50;
  color: white;
  padding: 1rem;
}

.sidebar h3 {
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid #3c5060;
}

.sidebar nav a {
  display: block;
  padding: 0.5rem;
  color: #b8c7ce;
  text-decoration: none;
}

.sidebar nav a:hover {
  background: #3c5060;
  color: white;
}

.content {
  flex: 1;
  padding: 2rem;
}
</style>

在页面中指定使用这个布局:

pages/admin/index.vue

复制代码
<script setup lang="ts">
definePageMeta({
  layout: 'admin'  // 指定使用 admin 布局
})
</script>

<template>
  <div>
    <h1>管理后台首页</h1>
    <p>欢迎回来,管理员</p>
  </div>
</template>

definePageMeta 是 Nuxt 提供的编译时宏,用于定义页面元信息,包括布局、中间件等。

三、动态切换布局

有时候同一个页面在不同状态下需要不同布局。比如用户登录前后:

复制代码
<script setup lang="ts">
const { loggedIn } = useUserSession()

// 根据登录状态动态选择布局
definePageMeta({
  layout: computed(() => loggedIn.value ? 'default' : 'guest')
})
</script>

或者用 setPageLayout 函数动态切换:

复制代码
<script setup lang="ts">
const isDark = ref(false)

// 切换布局
const toggleLayout = () => {
  isDark.value = !isDark.value
  setPageLayout(isDark.value ? 'dark' : 'default')
}
</script>

四、布局嵌套

复杂的系统可能需要布局嵌套。比如一个两栏布局,左侧固定,右侧是内容区,而内容区又需要默认布局的头部和底部。

创建 layouts/two-column.vue

复制代码
<template>
  <div class="two-column">
    <aside class="left-panel">
      <slot name="sidebar" />
    </aside>
    <div class="right-panel">
      <slot name="content" />
    </div>
  </div>
</template>

layouts/default.vue 中使用:

复制代码
<template>
  <div class="layout">
    <header>...</header>
    
    <main>
      <NuxtLayout name="two-column">
        <template #sidebar>
          侧边栏内容
        </template>
        <template #content>
          <slot />  <!-- 页面内容 -->
        </template>
      </NuxtLayout>
    </main>
    
    <footer>...</footer>
  </div>
</template>

五、布局中传递数据

布局和页面之间可以通过 props 传递数据。在布局中定义 props:

复制代码
<!-- layouts/default.vue -->
<script setup lang="ts">
const props = defineProps<{
  title?: string
}>()
</script>

<template>
  <div class="layout">
    <header>
      <h1>{{ title || '我的网站' }}</h1>
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>

页面中通过 definePageMeta 传递:

复制代码
<script setup lang="ts">
definePageMeta({
  layout: 'default',
  layoutProps: {
    title: '用户中心'
  }
})
</script>

六、命名插槽

布局支持命名插槽,让页面可以往不同区域填充内容:

复制代码
<!-- layouts/default.vue -->
<template>
  <div>
    <header>
      <slot name="header">
        <nav>默认导航</nav>
      </slot>
    </header>
    
    <main>
      <slot />
    </main>
    
    <footer>
      <slot name="footer">
        <p>默认底部</p>
      </slot>
    </footer>
  </div>
</template>

页面中:

复制代码
<template>
  <NuxtLayout>
    <template #header>
      <nav>自定义导航</nav>
    </template>
    
    <div>页面内容</div>
    
    <template #footer>
      <p>自定义底部</p>
    </template>
  </NuxtLayout>
</template>

总结

今天学习了 Nuxt 布局系统:

功能 实现方式
默认布局 layouts/default.vue 自动应用
自定义布局 definePageMeta({ layout: 'xxx' })
动态切换 setPageLayout() 或 computed
布局嵌套 在布局中使用 <NuxtLayout>
传递数据 layoutProps 配置

布局系统让你的页面框架统一管理,改一处全局生效。对于企业级项目来说,这是必不可少的利器。

下一篇文章,我们聊聊页面过渡动画,让页面切换更丝滑。


有帮助就点个赞吧!有问题评论区见 💪

相关推荐
前端那点事27 分钟前
Vue线上代码调试全攻略(安全无侵入,新手也能上手)
前端·vue.js
前端那点事30 分钟前
Vue批量文件上传并发踩坑指南:3步解决阻塞、限流、进度混乱
前端·面试
桔筐1 小时前
Vue3 v-model 双向绑定导致循环触发的坑
前端·javascript·vue.js
Alice-YUE1 小时前
前端图片优化完全指南:从格式到加载的全面提速方案
前端·笔记·学习
fen_fen1 小时前
下载Chrome浏览器对应的Driver
前端·chrome
路光.1 小时前
ReferenceError:Can‘t find variable:structureClone
前端·javascript·html·vue2
前端那点事1 小时前
内存泄漏排查全指南:从场景识别到工具实操,新手也能上手
前端·vue.js
我这一生如履薄冰~1 小时前
浏览器多窗口同开一页面,数据同步更新(纯前端方案)
前端·javascript
Alice-YUE1 小时前
前端性能优化完全指南:从指标到实战
前端·学习·性能优化
Momo__1 小时前
Web Speech API 语音识别与合成详解
前端·javascript