똑같은 삽질은 2번 하지 말자

Nuxt3 vol.2 본문

카테고리 없음

Nuxt3 vol.2

곽빵 2024. 6. 27. 22:01

개요

Nuxt3의 강의를 보면서 새롭게 습득한 사실을 정리

 

 

router.push를 이용하는 것 보다 NuxtLink나 RouterLink를 쓰자.

NuxtLink나 RouterLink를 이용하면 a태그로 렌더링이 되기 때문에 SEO최적화에 도움이 될 수 있다.

<NuxtLink v-slot="{ navigate }" custom :to="`/course/${courseSlug}`">
  <CourseCard
    :thumbnail="thumbnail"
    :title="title"
    :sub-title="subtitle"
    @click="navigate"
  />
</NuxtLink>
  • custom: a태그로 렌더링이 안되게끔 하는 속성 (NuxtLink를 쓰자! 라는 이유와 모순되지만 이런한 속성이 있다는 사실을 기록하고자 했다.)
  • navigate: router.push와 같은 역할은 하는 함수

 

NuxtPage 컴포넌트

NuxtPage 내장 컴포넌트는 RouterView를 래핑하고 있는 형태의 컴포넌트이다.

 

특징으로

  • (같은 페이지 컴포넌트에서) path가 변할 때 마다 리렌더링된다. (RouterView 컴포넌트는 처음에 마운트 될 때 한번만 렌더링된다.)
  • pageKey라는 props를 이용하면 쿼리 파라미터가 변경될 때도 리렌더링 되게끔 할 수 있다.

 

definePageMeta

페이지 컴포넌트에 대한 메타데이터를 설정할 때 사용하는 함수이다.

<script lang="ts">
definePageMeta({
  title: 'Course',
  description: '웹 개발 입문부터 실전까지 학습하세요',
  key: '리렌더링 여부를 결정하는 값',
  keepAlive: true,
  alias: ['/a', 'b', '/c']
});
</script>

 

  • title, description:  메타태그
  • key: 함수의 파라미터로써 설정할 수 있는데 쿼리 파라미터 변화가 페이지의 리렌더링으로 이어지는 걸 원하면 route의 fullPath를 키 값으로 설정해서 넘기면 된다.
  • keepAlive: true일때 Vue3의 <KeepAlive> 라는 내장 컴포넌트가 페이지 컴포넌트를 래핑한다. 페이지의 이동시 페이지 컴포넌트 자체가 캐싱되면서 다시 돌아올 때 따로 렌더링을 하지 않고 캐싱했던 페이지 컴포넌트를 가져오기만 한다. 동적 하위 경로가 있는 상위 경로에서 경로 변경시 페이지 상태를 유지하려는 경우에 활용될 수 있다.
  • alias: 문자열이나 배열을 설정할 수 있으면 여러가지의 path를 하나의 페이지로 이동되게끔 할 수 있다.


NuxtLink 컴포넌트

RouterLink 컴포넌트와 HTML의 <a> 태그를 대체하는 내장 컴포넌트이다. 

  • to 에 설정된 링크값을 보고 내부의 페이지인지 외부의 페이지 인지에 따라 href, rel값들을 적절하게 설정한다.
  • Prefetching이라는 강력한 기능을 지원하는데 이는 viewport 내부에 있는 NuxtLink가 있다면 해당 페이지 컴포넌트의 스크립트를 미리 가져와 로드를 해 놓는다. 이로 인해 해당 링크를 클릭했을때 페이지 전환이 빠르게 일어나며 좋은 유저경험을 제공할 수 있게 된다.

 

layout

  • app.vue에 <NuxtLayout> 컴포넌트를 추가하면 레이아웃층이 활성화 된다.
  • 따로 레이아웃을 설정하지 않으면 layouts/default.vue가 적용된다.
  • 특정한 레이아웃을 사용하고 싶을 경우 definePageMeta의 layout속성을 이용
  • 동적 레이아웃을 하고 싶은 경우 setPageLayout함수를 이용
  • 특정 디렉터리의 하위의 페이지들에 전부 같은 레이아웃을 적용하고 싶을 경우에는 중첩 라우트를 활용

 

plugins

  • plugins라는 디렉터리를 만들어서 그 하위에 파일을 만들면 자동으로 import된다.
  • export default defineNuxtPlugin(nuxtApp => { // nuxtApp에 접근이 가능 })

 

createError

nuxt3에서 가지고 있는 내부 객체로써 발생한 에러를 다루고 제어하는 것에 관한 여러 기능을 제공한다.

createError({
  cause, // 에러의 원인 (다른 에러 객체 또는 메시지 등)
  data, // 추가적인 에러 데이터 (사용자 정의 데이터)
  message, // 에러 메시지 (문제에 대한 간결한 설명)
  name, // 에러의 이름 또는 유형 (예: 'ValidationError')
  stack, // 에러 스택 트레이스 (발생한 위치와 호출 스택)
  statusCode, // HTTP 상태 코드 (예: 404, 500)
  statusMessage, // HTTP 상태 메시지 (예: 'Not Found', 'Internal Server Error')
  fatal // 에러가 치명적인지 여부 (페이지를 완전히 중지시킬지 여부)
})

 

클라이언트 쪽의 예시로써 밑과 같이 setup내부에 넣어서 페이지에 필수적인 데이터가 없을시 404에러로 돌리는 등으로 활용할 수 있다.

<script setup lang="ts">
const route = useRoute()
const { data } = await useFetch(`/api`)
if (!data.value) {
  throw createError({
    statusCode: 404,
    statusMessage: '페이지를 찾을 수 없습니다'
  })
}
</script>

 

middleware

nuxt3에서는 미들웨어를 어떻게 사용할까?

밑과 같이 페이지 컴포넌트의 definePageMeta에서 사용할 미들웨어를 지정할 수 있다.

<script setup lang="ts">
definePageMeta({
  layout: 'admin',
  middleware: ['admin-only'],
});
</script>

admin-only는 미들웨어의 파일이름으로써 밑의 코드가 미들웨어로써 작동된다.

 

middleware/admin-only.ts

export default defineNuxtRouteMiddleware(() => {
  const { isAdmin, isAuthenticated } = useAuthUser();

  if (!isAuthenticated.value) {
    return navigateTo('/login');
  }
  if (!isAdmin.value) {
    return navigateTo('/');
  }
});

미들웨어는 서버 사이드와 클라이언트 사이드에서 각각 실행되며 process.server나 process.client를 이용해 각각의 사이드에서 필요한 로직만을 실행할 수 있다.

 

다른 특징

  • middleware/xxx.global.ts로 하면 definePageMeta에서 지정을 안해도 전역적으로 실행되는 글로벌 미들웨어가 된다.
  • 글로벌 미들웨어는 알파벳순으로 실행된다.
Comments