pages

Nuxt는 웹 애플리케이션 내에서 경로를 생성하기 위한 파일 기반 라우팅을 제공한다.

 

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

 

페이지는 Vue 구성 요소이며 Nuxt가 지원하는 유효한 확장자(기본적으로 .vue, .js, .jsx, .mjs, .ts 또는 .tsx)를 가질 수 있다.

 

Nuxt는 ~/pages/ 디렉토리의 모든 페이지에 대한 경로를 자동으로 생성한다.

 

pages/index.vue

<!--
pages/index.vue
-->

<template>
  <h1>Index page</h1>
</template>

 

pages/index.ts

// pages/index.ts

// https://vuejs.org/guide/extras/render-function.html
export default defineComponent({
  render () {
    return h('h1', 'Index page')
  }
})

 

pages/index.tsx

// pages/index.tsx

// https://nuxt.com/docs/examples/advanced/jsx
// https://vuejs.org/guide/extras/render-function.html#jsx-tsx
export default defineComponent({
  render () {
    return <h1>Index page</h1>
  }
})

 

pages/index.vue 파일은 애플리케이션 경로 '/' 에 매핑된다.

 

app.vue 을 사용하는 경우 <NuxtPage/> 컴포넌트를 사용하여 현재 페이지를 표시해야 한다.

 

app.vue

<!-- 
app.vue
-->

<template>
  <div>
    <!-- Markup shared across all pages, ex: NavBar -->
    <NuxtPage />
  </div>
</template>

 

페이지단일 루트 요소가 있어야 한다.  트랜지션 페이지 사이의 HTML 주석도 엘리먼트로 간주된다.

 

즉, 경로가 서버에서 렌더링되거나 정적으로 생성되면 내용을 올바르게 볼 수 있지만 클라이언트 측 탐색 중에 해당 경로를 탐색하면 경로 간 전환이 실패하고 경로가 렌더링되지 않는 걸 보게된다.

 

다음은 단일 루트 엘리먼트가 있는 페이지의 모습을 보여주는 몇 가지 예이다.

 

pages/working.vue

<!--
pages/working.vue
-->

<template>
  <div>
    <!-- This page correctly has only one single root element -->
    Page content
  </div>
</template>

 

pages/bad-1.vue

<!--
pages/bad1-vue
-->

<template>
  <!-- This page will not render when route changes during client side navigation, because of this comment -->
  <div>Page content</div>
</template>

 

pages/bad-2.vue

<!--
pages/bad-2.vue
-->

<template>
  <div>This page</div>
  <div>Has more than one root element</div>
  <div>And will not render when route changes during client side navigation</div>
</template>

 

동적 경로

대괄호 안에 무엇이든 넣으면 동적 경로 매개변수로 변환된다. 파일 이름이나 디렉토리 내에서 여러 매개변수는 물론 비동적 텍스트까지 혼합하고 일치시킬 수 있다.

 

매개변수를 선택 사항으로 설정하려면 매개변수를 이중 대괄호로 묶어야 한다. 예를 들어 ~/pages/[[slug]]/index.vue 또는 ~/pages/[[slug]].vue는 /  /test 모두와 일치한다.

 

디렉토리 구조

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

위의 예에서 $route 객체를 통해 컴포넌트 내의 group/id 에 액세스할 수 있다.

 

pages/users-[group]/[id].vue

<!--
pages/users-[group]/[id].vue
-->

<template>
  <p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>

/users-admins/123 으로 이동하면 아래가 렌더링된다.

<p>admins - 123</p>

 

Composition API를 사용하여 경로에 액세스하려는 경우 Options API의 this.$route와 같이 경로에 액세스할 수 있는 전역 useRoute 함수가 있다.

<script setup lang="ts">
const route = useRoute()

if (route.params.group === 'admins' && !route.params.id) {
  console.log('Warning! Make sure user is authenticated!')
}
</script>

 

명명된 상위 경로는 중첩된 동적 경로보다 우선순위를 갖는다. /foo/hello 경로의 경우 ~/pages/foo.vue가 ~/pages/foo/[slug].vue보다 우선순위를 갖는다. /foo 및 /foo/hello를 다른 페이지와 일치시키려면 ~/pages/foo/index.vue 및 ~/pages/foo/[slug].vue를 사용하자.

 

포괄 경로 (Catch-all Route)

포괄 경로가 필요한 경우 [...slug].vue와 같은 이름의 파일을 사용하여 경로를 만든다. 이는 해당 경로 아래의 모든 경로와 일치한다.

 

pages/[...slug].vue

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

 

/hello/world 로 이동하면 아래가 렌더링된다.

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

 

중첩된 경로

<NuxtPage> 을 사용하여 중첩 경로를 표시할 수 있다.

 

디렉토리 구조

-| 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 구성요소를 표시하려면 <NuxtPage> 구성요소를 pages/parent.vue 안에 삽입해야 한다.

 

pages/parent.vue

<!--
pages/parent.vue
-->

<template>
  <div>
    <h1>I am the parent view</h1>
    <NuxtPage :foobar="123" />
  </div>
</template>

 

하위 경로 키

<NuxtPage> 컴포넌트가 다시 렌더링될 때(예: 트랜지션의 경우) 더 많은 제어를 원할 경우 pageKey prop을 통해 문자열이나 함수를 전달하거나 definePageMeta 를 통해 키 값을 정의할 수 있다.

 

pages/parent.vue

<!--
pages/parent.vue
-->

<template>
  <div>
    <h1>I am the parent view</h1>
    <NuxtPage :page-key="route => route.fullPath" />
  </div>
</template>

 

대안으로

 

pages/child.vue

<!--
pages/child.vue
-->

<script setup lang="ts">
definePageMeta({
  key: route => route.fullPath
})
</script>

 

다음 예는 pages/ 디렉터리가 앱 경로를 생성하는지 보여주는 예이다.

 

app.vue

<!--
app.vue
-->

<script setup lang="ts">
const router = useRouter()

const nav = [
  { label: 'Home', to: '/' },
  { label: 'About', to: '/about' },
  { label: 'Parent (index)', to: '/parent' },
  { label: 'Parent (b)', to: '/parent/b' },
  { label: 'Keyed child', onClick: () => router.push(`/parent/reload-${(Math.random() * 100).toFixed()}`) },
  { label: 'Non-Keyed child', onClick: () => router.push(`/parent/static-${(Math.random() * 100).toFixed()}`) },
]
</script>

<template>
  <NuxtExampleLayout dir="routing/pages" :nav="nav" current-route>
    <NuxtLoadingIndicator />
    <NuxtPage />
  </NuxtExampleLayout>
</template>

 

페이지 메타데이터

앱의 각 경로에 대한 메타데이터를 정의할 수 있다. <script>와 <script setup> 모두에서 작동하는 definePageMeta 매크로를 사용하여 이 작업을 수행할 수 있다.

<script setup lang="ts">
definePageMeta({
  title: 'My home page'
})
</script>

이 데이터는 route.meta 개체에서 앱의 나머지 부분 전체에 걸쳐 액세스할 수 있다.

<script setup lang="ts">
const route = useRoute()

console.log(route.meta.title) // My home page
</script>

 

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

 

defineEmits 또는 defineProps(Vue 문서 참조)와 매우 유사하게, definePageMeta는 컴파일러 매크로이기 때문에 컴포넌트 내에서 참조할 수 없도록 컴파일된다. 대신 전달된 메타데이터가 컴포넌트 밖으로 끌어올려진다. 따라서 페이지 메타 개체는 컴포넌트(또는 컴포넌트에 정의된 값)를 참조할 수 없지만, 가져온 바인딩을 참조할 수는 있다.

<script setup lang="ts">
import { someData } from '~/utils/example'

const title = ref('')

definePageMeta({
  title,  // This will create an error
  someData
})
</script>

 

특수한 메타데이터

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

 

alias
페이지 별칭을 정의할 수 있다. 이를 통해 다른 경로에서 동일한 페이지에 액세스할 수 있다. vue-router 문서에 정의된 대로 문자열이거나 문자열 배열일 수 있다.


keepalive
 definePageMeta에서 keepalive: true를 설정하면 Nuxt는 자동으로 Vue <KeepAlive> 컴포넌트에서 페이지를 래핑한다. 예를 들어 동적 하위 경로가 있는 상위 경로에서 경로 변경 시 페이지 상태를 유지하려는 경우 이 작업을 수행하는 것이 유용할 수 있다.


상위 경로의 상태를 보존하는 것이 목표인 경우 <NuxtPage keepalive /> 구문을 사용하. <KeepAlive>에 전달되도록 속성을 설정할 수도 있다(여기에서 전체 목록 참조).


nuxt.config에서 이 속성에 대한 기본값을 설정할 수 있다.

 

key

위 '하위 경로 키' 섹션의 pages/child.vue 참조


layout
경로를 렌더링하는데 사용되는 레이아웃을 정의할 수 있다. 어떤 방식으로든 반응적으로 만들려는 경우 false(레이아웃을 비활성화하기 위해), 문자열 또는 ref/computed 될 수 있다. 레이아웃에 대해 자세히 알아보려면...

 

layoutTransition 과 pageTransition
페이지와 레이아웃을 래핑하는 <transition> 컴포넌트에 대한 트랜지션 속성을 정의하거나 false를 전달하여 해당 경로에 대한 <transition> 래퍼를 비활성화할 수 있다. 여기에서 전달할 수 있는 옵션 목록을 보거나 트랜지션 작동 방식에 대해 자세히 알아볼 수 있다.


nuxt.config에서 이러한 속성에 대한 기본값을 설정할 수 있다.


middleware
이 페이지를 로드하기 전에 적용할 미들웨어를 정의할 수 있다. 일치하는 상위/하위 경로에 사용되는 다른 모든 미들웨어와 병합된다. 문자열, 함수(전역 사전 보호 패턴을 따르는 익명/인라인 미들웨어 함수- anonymous/inlined middleware function following the global before guard pattern) 또는 문자열/함수의 배열일 수 있다. 명명된 미들웨어에 대해 자세히 알아보자.


name
이 페이지 경로의 이름을 정의할 수 있다.

 

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

 

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

페이지에 사용자 정의 메타데이터를 추가하는 경우 타입이 안전한 방식으로 수행되는 것이 좋다. definePageMeta 에서 허용하는 객체 유형을 확장할 수 있다.

 

index.d.ts

// index.d.ts

declare module '#app' {
  interface PageMeta {
    pageType?: string
  }
}

// It is always important to ensure you import/export something when augmenting a type
export {}

 

네비게이션

Nuxt 3에서는 navigateTo() 유틸리티 메소드를 통해 프로그래밍 방식으로 탐색할 수 있습니다. 이 유틸리티 메서드를 사용하면 앱에서 사용자를 프로그래밍 방식으로 탐색할 수 있다. 이는 사용자로부터 입력을 받아 애플리케이션 전체에서 동적으로 탐색하는 데 유용하다. 아래 예에는 사용자가 검색 양식을 제출할 때 호출되는 navigate() 라는 간단한 메서드가 있다.

항상 await navigateTo 하거나 함수를 반환하여 결과를 연결하자.

 

<script setup lang="ts">
const name = ref('');
const type = ref(1);

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

 

커스텀 라우팅

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

참고) Docs > Guide > Going Further > Custom Routing

 

여러 페이지 디렉토리

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

 

그러나 Nuxt Layers를 사용하여 앱 페이지 그룹을 만들 수도 있다.

 

디렉토리 구조

-| 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

// nuxt.config.ts

export default defineNuxtConfig({
  extends: ['./some-app'],
})

 

참고) Docs > Guide > Going Further > Layers

'Nuxt 공식문서 번역 > Directories' 카테고리의 다른 글

public  (0) 2023.12.17
plugins  (1) 2023.12.17
node_modules  (0) 2023.12.17
modules  (0) 2023.12.17
middleware  (1) 2023.12.17
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유