레이아웃의 이름은 kebab-case로 정규화됩니다. someLayout.vue로 저장하여도, 사용할 때는 아래와 같이 사용 가능합니다.
<!-- pages/index.vue -->
<template>
<div>
<h1>홈 페이지</h1>
</div>
</template>
<script>
export default {
layout: 'some-layout' // 케밥 케이스로 정규화된 이름 사용
}
</script>
NuxtLayout 컴포넌트를 호출하고, 별도의 name을 지정하지 않으면 layouts/default.vue에 정의한 레이아웃이 사용됩니다. 만약 작성하는 프로젝트에 레이아웃이 하나만 존재한다면, app.vue에 레이아웃을 작성하여 사용하는 것이 권장됩니다.
동적으로 레이아웃을 변경하고자 할 때 setPageLayout 함수를 사용할 수 있습니다.
<template>
<div class="q-pa-md">
<div class="q-my-xl text-center q-gutter-md">
<q-btn
label="default layout"
color="dark"
@click="changePageLayout('default')"
/>
<q-btn
label="admin layout"
color="dark"
@click="changePageLayout('admin')"
/>
</div>
</div>
</template>
<script setup lang="ts">
import type { LayoutKey } from '#build/types/layouts';
const changePageLayout = (layout: LayoutKey) => {
setPageLayout(layout);
};
definePageMeta({
layout: false,
});
</script>
<style scoped></style>
q-btn을 클릭할 때마다 default 혹은 admin으로 레이아웃을 변경하는 예제입니다.
#build/ 경로는 Nuxt가 빌드 시점에 자동으로 생성하는 경로이며, #build/types/layouts는 레이아웃과 관련된 타입들을 정의하는 파일입니다. Nuxt는 빌드 시점에 프로젝트 내의 레이아웃 파일들을 분석하고, 이에 대한 타입 정보를 생성합니다.
위 코드에서는 타입스크립트를 사용하고 있기 때문에 input으로 전달할 layout의 타입을 지정해야 하므로 LayoutKey가 사용되었습니다.
<template>
<div>
<NuxtLayout name="admin">
<template #header>
<q-header elevated class="bg-primary text-white">
<q-toolbar>
<q-toolbar-title>Vue & Nuxt Mastery Admin</q-toolbar-title>
</q-toolbar>
</q-header>
</template>
<div class="q-my-xl text-center">
<div class="text-h4">레이아웃 재정의</div>
<p class="q-mt-sm text-grey-8">
Admin Layout 실습을 위한 페이지 입니다.
</p>
</div>
</NuxtLayout>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: false,
});
</script>
<style scoped></style>
definePageMeta에 layout을 false로 지정하여 레이아웃을 없애고 name을 admin으로 설정하여 NuxtLayout 컴포넌트를 직접 작성하였습니다. admin 레이아웃이 named slot으로 header를 받는다고 할 때, 위 코드처럼 레이아웃을 재정의하여 사용 가능합니다.
이런 디렉토리 구조에서 custom 디렉토리 하위의 페이지들에는 'custom' 레이아웃이 일괄적으로 적용되게하려면 어떻게 해야할까요?
pages/custom.vue
<template>
<NuxtLayout name="custom">
<NuxtPage />
</NuxtLayout>
</template>
<script setup lang="ts">
definePageMeta({
layout: false,
layoutTransition: false,
});
</script>
<style scoped></style>
중첩 라우팅에서 배웠듯, localhost:3000/custom으로 접근 시 pages/custom.vue가 랜더링 되고, pages/custom/xxx.vue의 내용이 pages/custom.vue의 NuxtPage에 렌더링되기 때문에 중첩 라우팅을 응용하여 레이아웃을 일괄 적용할 수 있습니다.