
Nuxt는 components/경로에 있는 파일컴포넌트를 자동으로 import 합니다.
이 때 파일명은 pascal case로 작성되어야 합니다.
아래와 같은 폴더구조의 프로젝트가 있다고 가정해봅시다.
-| components/
---| MainVisual.vue
---| MainCustomer.vue
---| MainFunction.vue
vue에서는 다음과 같이 컴포넌트를 일일이 import 해서 사용해왔습니다.
<template>
<div>
<MainVisual />
<MainCustomer />
<MainFunction />
</div>
</template>
<script setup>
import MainVisual from '@/components/MainVisual.vue';
import MainCustomer from '@/components/MainCustomer.vue';
import MainFunction from '@/components/MainFunction.vue';
</script>
Nuxt에서는 따로 import 하지 않아도 파일명으로 자동 import가 됩니다.
<template>
<div>
<MainVisual />
<MainCustomer />
<MainFunction />
</div>
</template>
-| components/
---| base/
-----| foo/
-------| Button.vue
이렇게 component 폴더에 하위 폴더가 있는 경우에는 Nuxt Auto import 규칙에 따라 모든 경로를 포함한 컴포넌트 이름이 생성됩니다.
<BaseFooButton />
파일명은
Button.vue인데 import한 컴포넌트명이BaseFooButton라면 혼동이 있을 수 있으니,Button.vue파일을 처음부터BaseFooButton.vue로 작성하거나, 혹은 더 자세하게CommonButton.vue등으로 지정하는것을 권장합니다.
필요한 경우 nuxt.config.ts에서 자동 컴포넌트 등록을 비활성화할 수 있습니다.
// nuxt.config.ts
export default defineNuxtConfig({
components: false
})
path를 기준으로 하지 않고 파일명 그 자체로 import 하려면 pathPrefix: false 를 활용할 수 있습니다.
// nuxt.config.ts
export default defineNuxtConfig({
components: [
{
path: '~/components',
pathPrefix: false,
},
],
});
위와같이 설정 하면
~/components/Some/MyComponent.vue 경로의 파일도
<SomeMyComponent> 가 아닌 <MyComponent>로 사용할 수 있습니다.
-| components/
---| (home)/
-----| HelloWorld.vue
폴더명에 ()를 입력하면 해당 경로는 제외되어 <HomeHelloWorld>가 아닌 <HelloWorld>로 사용할 수 있습니다.
pages 폴더를 통해 Nuxt3는 라우트 설정 파일 없이도 복잡한 라우팅 시스템을 쉽게 구축할 수 있도록 돕습니다.
단순히 파일을 추가하고 이름을 지정함으로써 라우트를 확장할 수 있고, 이는 개발 과정을 더욱 빠르고 효율적으로 만듭니다.
pages/
--| users/
-----| _id.vue
-----| index.vue
--| about.vue
--| index.vue
이 구조는 다음과 같은 URL 패턴을 생성합니다:
/ → pages/index.vue
/about → pages/about.vue
/users → pages/users/index.vue
/users/:id → pages/users/_id.vue (:id는 동적 파라미터입니다)
먼저 app.vue 파일에 <NuxtPage> 컴포넌트를 추가합니다.
// app.vue
<template>
<div>
<NuxtPage />
</div>
</template>
pages/index.vue 경로에 아래의 파일을 작성하면 자동으로 / 경로에 매핑됩니다.
<template>
<h1>Index page</h1>
</template>
pages는 반드시 단일 루트 요소를 가져야 합니다.
<template>
<div>이 화면은</div>
<div>한 개의 루트를 가지고 있지 않아서</div>
<div>랜더링 되지 않습니다</div>
</template>
이 때 주의할 점은 주석도 요소로 간주된다는 점 입니다.
<template>
<!-- 주석이 첫 번째 요소로 간주되어 이 페이지는 랜더링 되지 않습니다. -->
<div>Page content</div>
</template>
Nuxt 3에서는 페이지 기반 라우팅이 기본으로 제공되므로, meta 정보를 페이지 파일 내에서 정의하고, 필요한 컴포넌트에서는 이를 자동으로 참조할 수 있습니다.
router.js
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/product',
name: 'Product',
component: () => import('@/views/ProductView.vue'),
meta: { header: 'product', title: 'Product' },
},
...
],
});
SubHeader.vue
<template>
<div
class="sub-header"
:style="{
backgroundImage: `url(/assets/images/img-header_${page}.png)`,
}"
>
<h1 class="sub-header__title">{{ title }}</h1>
</div>
</template>
<script setup>
defineProps({
page: {
type: String,
default: 'function',
},
title: {
type: String,
default: '',
},
});
</script>
Parent.vue
<SubHeader :page="$route.meta.header" :title="$route.meta.title" />
SubHeader.vue에서 작성된 Props를 Parent.vue에서 router.js 에 작성된 meta data로 설정한 코드 입니다.
각 페이지 컴포넌트에서 현재 페이지의 meta 정보를 자동으로 참조하고, props를 전달받지 않고 필요한 값을 직접 가져옵니다.
// 각 페이지 컴포넌트에서 definePageMeta를 사용하여 meta 정보를 설정합니다.
<script setup>
definePageMeta({
header: 'product',
title: 'Product',
});
</script>
SubHeader.vue
<template>
<div
class="sub-header"
:style="{
backgroundImage: `url(/assets/images/img-header_${page}.png)`,
}"
>
<h1 class="sub-header__title">{{ title }}</h1>
</div>
</template>
<script setup>
// 현재 라우트 정보 가져오기
const route = useRoute();
// `meta`에서 `header`와 `title` 값을 가져오기
const page = ref(route.meta.header || '');
const title = ref(route.meta.title || '');
watch(
() => route.fullPath, // `fullPath`를 사용하여 라우터 상태가 변경될 때마다 추적
() => {
page.value = route.meta.header || '';
title.value = route.meta.title || '';
},
{ immediate: true }, // 즉시 실행하여 처음 값을 설정
);
</script>
Parent.vue
<SubHeader />
definePageMeta({
title: 'My Page', // 페이지 제목
layout: 'custom', // 사용할 레이아웃
middleware: ['auth'], // 적용할 미들웨어
pageTransition: { // 페이지 전환 효과
name: 'fade'
},
key: 'custom-key', // 페이지 키
keepalive: true, // 컴포넌트 캐싱
// 커스텀 메타 데이터
customMeta: {
header: 'product',
description: 'This is a product page'
}
})
참고자료
Nuxt3 공식문서