iBetter Books
수정

Ch 03. 중첩 라우팅과 레이아웃

대부분의 웹 서비스는 모든 페이지에서 공통으로 보이는 헤더와 푸터가 있습니다. 관리자 페이지는 일반 사용자 페이지와 다른 구조를 가질 수도 있습니다. 이런 공통 구조를 매 페이지마다 복사하는 것은 비효율적입니다. Nuxt.js의 레이아웃 시스템이 이 문제를 깔끔하게 해결해줍니다.

기본 레이아웃

layouts/default.vue 파일을 만들면 별도로 지정하지 않은 모든 페이지에 이 레이아웃이 자동으로 적용됩니다. 레이아웃 파일에서 <slot />이 있는 위치에 각 페이지의 내용이 삽입됩니다.

<!-- layouts/default.vue -->
<template>
  <div>
    <header>공통 헤더</header>
    <main>
      <slot />
    </main>
    <footer>공통 푸터</footer>
  </div>
</template>

그리고 app.vue에서 <NuxtLayout />으로 레이아웃을 활성화합니다.

<!-- app.vue -->
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

이렇게 설정하면 모든 페이지가 헤더와 푸터 사이에 렌더링됩니다.

다른 레이아웃 지정하기

관리자 페이지처럼 별도의 레이아웃이 필요하다면 layouts/admin.vue 파일을 만들고, 해당 페이지에서 definePageMeta()로 레이아웃을 지정합니다.

<!-- layouts/admin.vue -->
<template>
  <div class="admin-wrapper">
    <aside>관리자 사이드바</aside>
    <main>
      <slot />
    </main>
  </div>
</template>
<!-- pages/admin/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
  layout: 'admin'
})
</script>

<template>
  <div>
    <h2>관리자 대시보드</h2>
  </div>
</template>

definePageMeta()는 Nuxt.js가 제공하는 특별한 매크로 함수입니다. 레이아웃 외에도 페이지 제목, 미들웨어, 트랜지션 등 여러 메타 정보를 설정할 수 있습니다.

레이아웃을 완전히 사용하지 않으려면 layout: false로 설정합니다.

중첩 라우트

하나의 페이지 안에 또 다른 라우터 뷰가 필요한 경우에는 중첩 라우트를 사용합니다. 부모 경로와 같은 이름의 .vue 파일과 폴더를 함께 만들면 됩니다.

pages/
├── settings.vue          ← 부모 컴포넌트 (NuxtPage 포함)
└── settings/
    ├── profile.vue       ← /settings/profile
    └── security.vue      ← /settings/security

부모 컴포넌트인 settings.vue에는 자식 페이지가 렌더링될 위치에 <NuxtPage />를 배치합니다.

<!-- pages/settings.vue -->
<template>
  <div>
    <nav>설정 메뉴</nav>
    <NuxtPage />
  </div>
</template>

/settings/profile로 접근하면 settings.vue<NuxtPage /> 자리에 profile.vue가 삽입됩니다. 탭 방식의 설정 페이지나 단계별 폼을 구현할 때 활용하면 편리합니다.