入门篇四: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 配置

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

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


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

相关推荐
恋猫de小郭2 小时前
你的 AI 不好用,可能只是它在演你,或者在闹情绪
前端·人工智能·ai编程
那我懂你的意思啦2 小时前
Vue2+Vue3学习
前端·vue.js·学习
@大迁世界2 小时前
17.在 React 中如何根据条件决定渲染哪个组件?
前端·javascript·react.js·前端框架·ecmascript
小则又沐风a2 小时前
类和对象----最终篇
java·前端·数据库
travel_wsy2 小时前
PLY三维模型在vue中的展示
前端·javascript·vue.js
还是大剑师兰特2 小时前
Vite + Vue 3 一体化开发调试插件:vite-plugin-vue-devtools
前端·javascript·vue.js
晓得迷路了2 小时前
栗子前端技术周刊第 123 期 - axios 包遭入侵、Babylon.js 9.0、Node.js 25.9.0...
前端·javascript·axios
Cobyte2 小时前
如何使用飞书机器人连接本地 AI Agent
前端·aigc·ai编程
starsky762382 小时前
深入理解 Web 容器:从反射扫描到服务器启动的完整实现
java·前端·tomcat