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가 삽입됩니다. 탭 방식의 설정 페이지나 단계별 폼을 구현할 때 활용하면 편리합니다.