nuxt logo

문서 번역(비공식)

pages

Nuxt는 파일 기반 라우팅을 제공하여 웹 애플리케이션 내에서 라우트를 생성합니다.

애플리케이션의 번들 크기를 줄이기 위해, 이 디렉토리는 선택 사항입니다. 즉, app.vue만 사용하는 경우 vue-router는 포함되지 않습니다. 페이지 시스템을 강제하려면 nuxt.config에서 pages: true를 설정하거나 app/router.options.ts를 사용하세요.

사용법

페이지는 Vue 컴포넌트이며 Nuxt가 지원하는 유효한 확장자를 가질 수 있습니다 (기본적으로 .vue, .js, .jsx, .mjs, .ts 또는 .tsx).

Nuxt는 ~/pages/ 디렉토리의 모든 페이지에 대해 자동으로 라우트를 생성합니다.

<template>
  <h1>인덱스 페이지</h1>
</template>

pages/index.vue 파일은 애플리케이션의 / 라우트에 매핑됩니다.

app.vue를 사용하는 경우, 현재 페이지를 표시하기 위해 <NuxtPage/> 컴포넌트를 사용해야 합니다:

app.vue
<template>
  <div>
    <!-- 모든 페이지에 걸쳐 공유되는 마크업, 예: NavBar -->
    <NuxtPage />
  </div>
</template>

페이지는 단일 루트 요소를 가져야 하며, 페이지 간 라우트 전환을 허용해야 합니다. HTML 주석도 요소로 간주됩니다.

이는 라우트가 서버 렌더링되거나 정적으로 생성될 때 그 내용을 올바르게 볼 수 있지만, 클라이언트 측 탐색 중에 해당 라우트로 이동할 때 라우트 간 전환이 실패하고 라우트가 렌더링되지 않는다는 것을 의미합니다.

단일 루트 요소를 가진 페이지가 어떻게 보이는지 설명하는 몇 가지 예가 있습니다:

<template>
  <div>
    <!-- 이 페이지는 올바르게 단일 루트 요소만 가지고 있습니다 -->
    페이지 내용
  </div>
</template>

동적 라우트

대괄호 안에 무언가를 넣으면 동적 라우트 매개변수로 변환됩니다. 여러 매개변수를 혼합하여 사용할 수 있으며, 파일 이름이나 디렉토리 내에 비동적 텍스트를 포함할 수도 있습니다.

매개변수를 _선택 사항_으로 만들고 싶다면, 두 개의 대괄호로 감싸야 합니다 - 예를 들어, ~/pages/[[slug]]/index.vue 또는 ~/pages/[[slug]].vue//test 모두에 매칭됩니다.

Directory Structure
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue

위의 예를 통해, 컴포넌트 내에서 $route 객체를 통해 group/id에 접근할 수 있습니다:

pages/users-[group\
<template>
  <p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>

/users-admins/123로 이동하면 다음과 같이 렌더링됩니다:

<p>admins - 123</p>

Composition API를 사용하여 라우트에 접근하고 싶다면, this.$route를 Options API에서 사용하는 것처럼 라우트에 접근할 수 있는 글로벌 useRoute 함수가 있습니다.

const route = useRoute()

if (route.params.group === 'admins' && !route.params.id) {
  console.log('경고! 사용자가 인증되었는지 확인하세요!')
}

이름이 지정된 부모 라우트는 중첩된 동적 라우트보다 우선합니다. /foo/hello 라우트의 경우, ~/pages/foo.vue~/pages/foo/[slug].vue보다 우선합니다. :br /foo/foo/hello를 다른 페이지로 매칭하려면 ~/pages/foo/index.vue~/pages/foo/[slug].vue를 사용하세요.

Catch-all 라우트

모든 라우트를 포괄하는 catch-all 라우트가 필요하다면, [...slug].vue와 같은 이름의 파일을 사용하여 생성할 수 있습니다. 이는 해당 경로 아래의 모든 라우트와 일치합니다.

pages/[...slug\
<template>
  <p>{{ $route.params.slug }}</p>
</template>

/hello/world로 이동하면 다음과 같이 렌더링됩니다:

<p>["hello", "world"]</p>

중첩 라우트

<NuxtPage>를 사용하여 중첩 라우트를 표시할 수 있습니다.

예시:

Directory Structure
-| pages/
---| parent/
-----| child.vue
---| parent.vue

이 파일 트리는 다음과 같은 라우트를 생성합니다:

[
  {
    path: '/parent',
    component: '~/pages/parent.vue',
    name: 'parent',
    children: [
      {
        path: 'child',
        component: '~/pages/parent/child.vue',
        name: 'parent-child'
      }
    ]
  }
]

child.vue 컴포넌트를 표시하려면 pages/parent.vue 내부에 <NuxtPage> 컴포넌트를 삽입해야 합니다:

pages/parent.vue
<template>
  <div>
    <h1>나는 부모 뷰입니다</h1>
    <NuxtPage :foobar="123" />
  </div>
</template>
pages/parent/child.vue
const props = defineProps(['foobar'])

console.log(props.foobar)

자식 라우트 키

<NuxtPage> 컴포넌트가 다시 렌더링되는 시점을 더 제어하고 싶다면 (예: 전환을 위해), pageKey prop을 통해 문자열이나 함수를 전달하거나 definePageMeta를 통해 key 값을 정의할 수 있습니다:

pages/parent.vue
<template>
  <div>
    <h1>나는 부모 뷰입니다</h1>
    <NuxtPage :page-key="route => route.fullPath" />
  </div>
</template>

또는 다음과 같이 할 수도 있습니다:

pages/parent/child.vue
definePageMeta({
  key: route => route.fullPath
})
샘플 코드 편집 및 미리보기examples > routing > pages

라우트 그룹

경우에 따라 파일 기반 라우팅에 영향을 주지 않는 방식으로 라우트 세트를 그룹화하고 싶을 수 있습니다. 이를 위해, 파일을 괄호로 감싼 폴더에 넣을 수 있습니다 - ().

예를 들어:

Directory structure
-| pages/
---| index.vue
---| (marketing)/
-----| about.vue
-----| contact.vue

이렇게 하면 앱에서 /, /about/contact 페이지가 생성됩니다. marketing 그룹은 URL 구조의 목적상 무시됩니다.

페이지 메타데이터

앱의 각 라우트에 대한 메타데이터를 정의하고 싶을 수 있습니다. <script><script setup>에서 작동하는 definePageMeta 매크로를 사용하여 이를 수행할 수 있습니다:

definePageMeta({
  title: '내 홈 페이지'
})

그런 다음 이 데이터는 앱의 나머지 부분에서 route.meta 객체를 통해 접근할 수 있습니다.

const route = useRoute()

console.log(route.meta.title) // 내 홈 페이지

중첩된 라우트를 사용하는 경우, 이러한 모든 라우트의 페이지 메타데이터는 단일 객체로 병합됩니다. 라우트 메타에 대한 자세한 내용은 vue-router 문서를 참조하세요.

defineEmits 또는 defineProps와 마찬가지로 (자세한 내용은 Vue 문서를 참조하세요), definePageMeta컴파일러 매크로입니다. 컴포넌트 내에서 참조할 수 없도록 컴파일됩니다. 대신, 전달된 메타데이터는 컴포넌트 외부로 이동됩니다. 따라서 페이지 메타 객체는 컴포넌트를 참조할 수 없습니다. 그러나 가져온 바인딩 및 로컬로 정의된 순수 함수를 참조할 수 있습니다.

반응형 데이터나 부작용을 일으키는 함수를 참조하지 않도록 주의하세요. 이는 예기치 않은 동작을 초래할 수 있습니다.

import { someData } from '~/utils/example'

function validateIdParam(route) {
  return route.params.id && !isNaN(Number(route.params.id))
}

const title = ref('')

definePageMeta({
  validate: validateIdParam,
  someData,
  title,    // 이렇게 하지 마세요, ref는 컴포넌트 외부로 이동됩니다
})

특별한 메타데이터

물론, 앱 전반에서 사용할 메타데이터를 정의할 수 있습니다. 그러나 definePageMeta로 정의된 일부 메타데이터는 특별한 목적을 가지고 있습니다:

alias

페이지 별칭을 정의할 수 있습니다. 이를 통해 다른 경로에서 동일한 페이지에 접근할 수 있습니다. 이는 vue-router 문서에 정의된 대로 문자열 또는 문자열 배열일 수 있습니다.

keepalive

definePageMeta에서 keepalive: true를 설정하면 Nuxt는 페이지를 Vue <KeepAlive> 컴포넌트로 자동으로 래핑합니다. 이는 예를 들어, 동적 자식 라우트를 가진 부모 라우트에서 라우트 변경 간 페이지 상태를 유지하려는 경우 유용할 수 있습니다.

부모 라우트의 상태를 유지하려는 경우 이 구문을 사용하세요: <NuxtPage keepalive />. <KeepAlive>에 전달할 props를 설정할 수도 있습니다 (전체 목록은 여기를 참조하세요).

이 속성의 기본값은 nuxt.config에서 설정할 수 있습니다.

key

위 참조.

layout

라우트를 렌더링하는 데 사용되는 레이아웃을 정의할 수 있습니다. 이는 false (레이아웃을 비활성화하기 위해), 문자열 또는 반응형으로 만들고 싶다면 ref/computed일 수 있습니다. 레이아웃에 대한 자세한 내용.

layoutTransitionpageTransition

페이지와 레이아웃을 래핑하는 <transition> 컴포넌트에 대한 전환 속성을 정의하거나 해당 라우트에 대해 <transition> 래퍼를 비활성화하려면 false를 전달할 수 있습니다. 전달할 수 있는 옵션 목록을 보거나 전환이 작동하는 방식에 대한 자세한 내용을 읽어보세요.

이 속성의 기본값은 nuxt.config에서 설정할 수 있습니다.

middleware

이 페이지를 로드하기 전에 적용할 미들웨어를 정의할 수 있습니다. 이는 일치하는 부모/자식 라우트에서 사용되는 다른 모든 미들웨어와 병합됩니다. 이는 문자열, 함수 (익명/인라인 미들웨어 함수로 글로벌 전역 가드 패턴을 따름), 또는 문자열/함수 배열일 수 있습니다. 이름이 지정된 미들웨어에 대한 자세한 내용.

name

이 페이지의 라우트에 대한 이름을 정의할 수 있습니다.

path

파일 이름으로 표현할 수 있는 것보다 더 복잡한 패턴이 있는 경우 경로 매처를 정의할 수 있습니다. 자세한 내용은 vue-router 문서를 참조하세요.

props

페이지 컴포넌트에 전달된 props로 라우트 params에 접근할 수 있습니다. 자세한 내용은 vue-router 문서를 참조하세요.

사용자 정의 메타데이터 타입 지정

페이지에 사용자 정의 메타데이터를 추가하는 경우, 타입 안전한 방식으로 수행하고 싶을 수 있습니다. definePageMeta에서 허용하는 객체의 타입을 확장할 수 있습니다:

index.d.ts
declare module '#app' {
  interface PageMeta {
    pageType?: string
  }
}

// 타입을 확장할 때는 항상 import/export를 통해 무언가를 보장하는 것이 중요합니다
export {}

네비게이션

앱의 페이지 간 네비게이션을 위해 <NuxtLink> 컴포넌트를 사용해야 합니다.

이 컴포넌트는 Nuxt에 포함되어 있으므로 다른 컴포넌트처럼 import할 필요가 없습니다.

pages 폴더의 index.vue 페이지로의 간단한 링크:

<template>
  <NuxtLink to="/">홈 페이지</NuxtLink>
</template>
이것도 참고 api > components > nuxt-link

프로그래매틱 네비게이션

Nuxt는 navigateTo() 유틸리티 메서드를 통해 프로그래매틱 네비게이션을 허용합니다. 이 유틸리티 메서드를 사용하면 앱 내에서 사용자를 프로그래매틱하게 네비게이션할 수 있습니다. 이는 사용자로부터 입력을 받아 애플리케이션 전반에 걸쳐 동적으로 네비게이션할 때 유용합니다. 이 예에서는 사용자가 검색 폼을 제출할 때 호출되는 navigate()라는 간단한 메서드가 있습니다.

항상 navigateToawait하거나 함수에서 반환하여 결과를 체인하세요.

const name = ref('');
const type = ref(1);

function navigate(){
  return navigateTo({
    path: '/search',
    query: {
      name: name.value,
      type: type.value
    }
  })
}

클라이언트 전용 페이지

.client.vue 접미사를 사용하여 페이지를 클라이언트 전용으로 정의할 수 있습니다. 이 페이지의 내용은 서버에서 렌더링되지 않습니다.

서버 전용 페이지

.server.vue 접미사를 사용하여 페이지를 서버 전용으로 정의할 수 있습니다. 클라이언트 측 네비게이션을 통해 페이지로 이동할 수 있지만, 자동으로 서버 컴포넌트로 렌더링되므로 페이지를 렌더링하는 데 필요한 코드는 클라이언트 측 번들에 포함되지 않습니다.

서버 전용 페이지는 단일 루트 요소를 가져야 합니다. (HTML 주석도 요소로 간주됩니다.)

사용자 정의 라우팅

앱이 커지고 복잡해짐에 따라 라우팅에 더 많은 유연성이 필요할 수 있습니다. 이러한 이유로 Nuxt는 라우터, 라우트 및 라우터 옵션을 다양한 방식으로 직접 노출하여 사용자 정의할 수 있습니다.

이것도 참고 guide > recipes > custom-routing

여러 페이지 디렉토리

기본적으로 모든 페이지는 프로젝트 루트의 pages 디렉토리에 있어야 합니다.

그러나 Nuxt Layers를 사용하여 앱의 페이지 그룹을 생성할 수 있습니다:

Directory Structure
-| some-app/
---| nuxt.config.ts
---| pages/
-----| app-page.vue
-| nuxt.config.ts
some-app/nuxt.config.ts
// some-app/nuxt.config.ts
export default defineNuxtConfig({
})
nuxt.config.ts
export default defineNuxtConfig({
  extends: ['./some-app'],
})
이것도 참고 guide > going-further > layers