[Nuxt3] components

Dohee Kang·2023년 4월 9일
2

Nuxt

목록 보기
4/4

  • components 디렉토리는 페이지 또는 다른 컴포넌트 내에서 가져올 수 있는 모든 Vue 컴포넌트를 저장한다.
  • Nuxt는 components 디렉토리에 있는 모든 컴포넌트를 자동으로 가져와서 별도로 import를 하여 가져오지 않아도 된다.
| components/
--| Header.vue
--| Footer.vue
<template>
  <div>
    <Header />
    <slot />
    <Footer />
  </div>
</template>

1. 커스텀 디렉토리

  • Nuxt는 기본적으로 components 디렉토리만 스캔한다. 만약 다른 디렉토리를 추가하거나 components 디렉토리의 하위 폴더 내에 파일을 컴포넌트로 인식하려면 nuxt.config.ts에 디렉토리를 추가하면 된다.
    • extensions : extenstions에 지정된 확장자를 가진 모든 파일은 컴포넌트로 취급
export default defineNuxtConfig({
  components: [
    { 
      path: '~/components/special-components', 
      prefix: 'Special',
      extensions: ['.vue'],
    },
  ]
})

2. 컴포넌트명

  • 아래와 같이 중첩된 디렉토리에 컴포넌트가 있는 경우 컴포넌트명은 경로 디렉토리와 파일명을 기반으로 생성된다.
  • 아래 예제는 base/foo 폴더에 Button.vue가 있으므로 컴포넌트명은 <BaseFooButton />이 된다.
| components/
--| base/
----| foo/
------| Button.vue

<BaseFooButton />
  • 만약 경로가 아닌 이름을 기준으로 컴포넌트명을 사용하려면 pathPrefixfalse로 지정한다.
export default defineNuxtConfig({
  components: [
    {
      path: '~/components',
+     pathPrefix: false,
    },
  ],
});

3. 동적 컴포넌트

  • <component :is="일부 계산된 컴포넌트"> 구문을 사용하려면 Vue에서 제공하는 resolveComponent()를 사용한다.
    • resolveComponent() : 변수가 아닌 문자열이어야 하며 컴포넌트명만 기입
<template>
  <component :is="clickable ? MyButton : 'div'" />
</template>

<script setup>
const MyButton = resolveComponent('MyButton')
</script>
  • 권장하진 않지만 모든 컴포넌트를 전역적으로 등록하여 사용하는 방법이 있다.
    • nuxt.config.ts에 등록하거나 components/global 디렉토리에 배치하여 등록
export default defineNuxtConfig({
  components: {
+     global: true,
+     dirs: ['~/components']
  },
})

4. 동적 import

  • 컴포넌트를 동적으로 import하려면 컴포넌트명 앞에 Lazy란 접두사만 추가하면 된다.
  • Lazy component는 적절한 순간까지 컴포넌트 로딩을 지연시킬 수 있어 JS 번들 크기를 최적화하는데 유용하다.
<template>
  <div>
    <TheHeader />
    <slot />
    <LazyTheFooter />
  </div>
</template>

5. 직접 import

  • Nuxt에서 자동으로 가져오는 기능을 우회해야 하는 경우 #components를 통해 컴포넌트를 명시적으로 가져올 수 있다.
<template>
  <div>
    <h1>Mountains</h1>
    <LazyMountainsList v-if="show" />
    <button v-if="!show" @click="show = true">Show List</button>
    <NuxtLink to="/">Home</NuxtLink>
  </div>
</template>

<script setup>
  import { NuxtLink, LazyMountainsList } from '#components'
  const show = ref(false)
</script>

6. <ClientOnly> 컴포넌트

  • 컴포넌트를 의도적으로 클라이언트 측에서만 렌더링하기 위해 <ClientOnly> 컴포넌트를 제공한다.
  • 컴포넌트를 클라이언트에서만 import하려면 클라이언트 전용 플러그인에 컴포넌트를 등록하면 된다.
<template>
  <div>
    <Sidebar />
    <ClientOnly>
      <!-- this component will only be rendered on client-side -->
      <Comments />
    </ClientOnly>
  </div>
</template>
  • 또는 .client 접미사를 추가하여 사용할 수 있다.
| components/
--| Comments.client.vue
<template>
  <div>
    <!-- this component will only be rendered on client side -->
    <Comments />
  </div>
</template>

💡 .client 컴포넌트는 마운트된 후에만 렌더링된다. 렌더링된 템플릿에 사용하려면 onMounted() 훅에 await nextTick()을 추가하면 된다.


profile
오늘은 나에게 어떤 일이 생길까 ✨

0개의 댓글