반응형

KaKao Map은 html script를 통해 지도를 불러올 수 있다.

Nuxt에서 html head에 script를 추가하기 위해서는  Nuxt Config에 다음을 작성하면 브라우저가 불러져 올때 script가 추가가 된다.

app: {
    head: {
      script: [
        {
          type: "text/javascript",
          src: `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.KAKAO_MAP_KEY}`,
        },
      ],
    },
  },
// kakaomap.vue

<script setup lang="ts">
interface IKakaoMapProps {
  width: number | string;
  height: number | string;
}
defineProps<IKakaoMapProps>();
onMounted(() => {
  //@ts-ignore
  kakao.maps.load(() => {
    const container = document.getElementById("map");
    const options = {
      //@ts-ignore
      center: new kakao.maps.LatLng(33.450701, 126.570667),
      level: 3,
    };
    //@ts-ignore
    const map = new kakao.maps.Map(container, options);
  });
});
</script>
<template>
  <div id="map" :style="`width:${width};height:${height}`"></div>
</template>
728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt3__Data Fetch  (0) 2023.11.22
NuxtJS__app, layout, pages, components, errorpage  (1) 2023.11.14
반응형

Data Fetch 

Nuxt의 문서에서 Data Fetch와 관련한 문서를 보면$fetch /  useAsyncData / useFetch 로 나누어져 있다. 

<script setup lang="ts">
// SSR 동안 데이터는 서버에서 한 번, 클라이언트에서 한 번, 총 두 번 가져옵니다.
const dataTwice = await $fetch('/api/item')

// SSR 중에는 데이터가 서버 측에서만 가져와 클라이언트로 전송됩니다.
const { data } = await useAsyncData('item', () => $fetch('/api/item'))

//useAsyncData + $fetch의 바로가기로 Fetch를 사용할 수도 있습니다.
const { data } = await useFetch('/api/item')
</script>

 

$fetch

(https://nuxt.com/docs/api/utils/dollarfetch)

$fetch는  클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있습니다 .

또한 useAsyncData로 래핑하지 않고 구성 요소에서 $fetch를 사용하면 데이터를 두 번 가져오게 됩니다.

처음에는 서버에서, 그 다음에는 하이드레이션 중에 클라이언트 측에서 다시 가져옵니다.

$fetch가 서버에서 클라이언트로 상태를 전송하지 않기 때문입니다.

따라서 클라이언트가 데이터를 다시 가져와야 하므로 가져오기는 양쪽에서 실행됩니다.

 

클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있다.

// ./page/contact.vue
<script setup lang="ts">
function contactForm() {
  $fetch('/api/contact', {
    method: 'POST',
    body: { hello: 'world '}
  })
}
</script>

<template>
  <button @click="contactForm">Contact</button>
</template>

$fetchNuxt 2용으로 만들어진 @nuxt/http  @nuxtjs/axios 대신 Nuxt에서 HTTP 호출을 수행하는 데 선호되는 방법입니다 .

useAsyncData

(https://nuxt.com/docs/api/composables/use-async-data)

useAsyncData는 SSR 친화적인 컴포저블에서 비동기적으로 확인되는 데이터에 대한 액세스를 제공합니다.

페이지, 컴포넌트 및 플러그인 내에서 useAsyncData를 사용하여 비동기적으로 확인되는 데이터에 액세스할 수 있습니다.

<script setup>
const { data, pending, error, refresh } = await useAsyncData(
  'mountains',
  () => $fetch('https://api.nuxtjs.dev/mountains')
)
</script>

Watch 매개변수

내장 watch옵션을 사용하면 변경 사항이 감지되면 페처 기능을 자동으로 다시 실행할 수 있습니다.

<script setup>
const page = ref(1)
const { data: posts } = await useAsyncData(
  'posts',
  () => $fetch('https://fakeApi.com/posts', {
    params: {
      page: page.value
    }
  }), {
    watch: [page]
  }
)
</script>

 

매개변수

key: 데이터 가져오기가 요청 전반에 걸쳐 적절하게 중복 제거될 수 있도록 보장하는 고유 키입니다. 키를 제공하지 않으면 의 인스턴스 행 번호와 파일 이름에 고유한 키가 useAsyncData생성됩니다.

handler: 실제 값을 반환해야 하는 비동기 함수(예:  undefined 또는 null 이면 안 됨). 그렇지 않으면 요청이 클라이언트 측에서 중복될 수 있습니다.

options:

  • server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
  • lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
  • immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
  • defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
  • transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
  • pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
  • watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
  • deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.

 

useFetch

(https://nuxt.com/docs/api/composables/use-fetch)

SSR 친화적인 컴포저블을 사용하여 API 엔드포인트에서 데이터를 가져옵니다. 

이 컴포저블은 AsyncData와 $fetch를 사용하는 데 편리한 wrapper를 제공합니다.

URL 및 fetch 옵션을 기반으로 키를 자동으로 생성하고 서버 경로를 기반으로 요청 URL에 대한 유형 힌트를 제공하며 API 응답 유형을 추론합니다. 

useFetch는 설정 기능, 플러그인 또는 경로 미들웨어에서 직접 호출할 수 있는 합성 파일입니다. 이것은 반응형 컴포저블을 반환하고  Nuxt 페이로드에 응답을 추가하는 작업을 처리하여 페이지가 렌더링간의 조화를 공급할 때 클라이언트 측의 데이터를 다시 가져오지 않고 서버에서 클라이언트로 전달할 수 있습니다.

<script setup>
const route = useRoute()

const { data, pending, error, refresh } = await useFetch(`https://api.nuxtjs.dev/mountains/${route.params.slug}`, {
  pick: ['title']
})
</script>

 

query를 사용해 fetching을 확장시킬수 있습니다.

const param1 = ref('value1')
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
  query: { param1, param2: 'value2' }
})

// https://api.nuxtjs.dev/mountains?param1=value1&param2=value2

Interceptors 사용이 가능하다

const { data, pending, error, refresh } = await useFetch('/api/auth/login', {
  onRequest({ request, options }) {
    // Set the request headers
    options.headers = options.headers || {}
    options.headers.authorization = '...'
  },
  onRequestError({ request, options, error }) {
    // Handle the request errors
  },
  onResponse({ request, response, options }) {
    // Process the response data
    localStorage.setItem('token', response._data.token)
  },
  onResponseError({ request, response, options }) {
    // Handle the response errors
  }
})

커스텀fetch 관련(https://nuxt.com/docs/examples/advanced/use-custom-fetch-composable)

매개변수

URL: 가져올 URL입니다.

Options( unjs/ofetch 옵션 및 AsyncDataOptions 확장 ):

모든 fetch option에는 computed와 ref의 값을 줄 수 있다. 이를 감시하고 업데이트된 경우 새 값으로 자동으로 새 요청이 수행된다.

 

options: useAsyncData의 옵션을 사용할수 있다. 

  • server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
  • lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
  • immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
  • defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
  • transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
  • pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
  • watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
  • deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.
//동일 문

const {data: items} = await useFetch('/api/params')


const {pending, data: items} = useFetch('/api/params',{
  lazy: false
  server: false // 클라이언트 사이드 렌더링 이 됨
})

const {pending, data: items} = await useLazyFetch('/api/params')

Transform Handler

const {data: items} = useFetch('/api/params',
 {
  lazy:false,
  transform:(items)=>{
    return items.map((item) => ({
      id: item.id
      title: item.title
      image: item.image
     }));
    }
  }
)

Pick Handler

const {data: items} = useFetch('/api/params',
 {
  lazy:false,
  pick:['id','title','image]
)

 

useAsyncData & useFetch 의 반환값

반환 값

  • data: 전달된 비동기 함수의 결과입니다.
  • pending: 데이터를 아직 가져오는 중인지 여부를 나타내는 부울입니다.
  • refresh/ execute: 함수에서 반환된 데이터를 새로 고치는 데 사용할 수 있는 함수입니다 handler.
  • error: 데이터 가져오기에 실패한 경우 오류 개체입니다.
  • status: 데이터 요청 상태를 나타내는 문자열( "idle", "pending", "success", "error").
  • 기본적으로 Nuxt는 refresh가 다시 실행되기 전에 완료될 때까지 기다립니다.
<script setup>
  const param1 = ref('value1')
  const { data:items, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
    query: { param1, param2: 'value2' }
  })
</script>

<template>
  <div v-if="pending">
    <p>로딩중</p>
  </div>
  
  <div v-else-if="error">
    <p>Error Code {{ error?.message }}</p>
  </div>
  
  <div v-else>
   <button @click="refresh"> 새로고침 </button>
   	<div>
     <div v-for="item in items" :key="item.id">
      {{item}}
     </div>
    </div>
  </div>
</template>

다중 Fetching

<script setup lang="ts">
const {
  pending,
  data: productInfo,
  refresh,
} = useAsyncData(
  "productInfo",
  async () => {
    const [products, catagories]: any = await Promise.all([
      $fetch("/api/products"),
      $fetch("/api/products/categories"),
    ]);
    return {
      products,
      catagories,
    };
  },
  {
    lazy: false,
    transform: (productInfo) => {
      return {
        catagories: productInfo.catagories,
        products: productInfo.products.map((product: any) => ({
          id: product.id,
          title: product.title,
          image: product.image,
        })),
      };
    },
  }
);
</script>
728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt Kakao Map 연동  (0) 2024.08.25
NuxtJS__app, layout, pages, components, errorpage  (1) 2023.11.14
반응형

Nuxt 프로젝트 생성

npx nuxi@latest init <project-name>

 

Nuxt 설치 후 
https://nuxt.com/docs/guide의 Directory Structure를 참고하여 자기가 필요한 기능들을 폴더로 만들고 해당파일을 만들면 그 기능이 활성화된다. 폴더를 만들땐 위의 링크에 나와있는데로 작성해야한다.

 

1.  app.vue

초기 파일에 app.vue파일에 내용을 다 지우고 작업을 시작하면된다.

//app.vue

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

 

2.  Layouts

layouts 관련 내용 (https://nuxt.com/docs/guide/directory-structure/layouts)

레이아웃을 만들기 위해 Root에 layouts라는 폴더를 만들고 기본이 되는 레이아웃을 파일을 만든다.ㅓ

기본이 되는 파일명은 default.vue가 되어야 한다.

//default.vue
<template>
  <div>
    <HeaderComp />
    <h1>this is layout</h1>
    <NuxtPage />
    <FooterComp />
  </div>
</template>

 

커스텀 레이아웃은 커스텀명.vue로 만들어야하고

//pages/페이지이름.vue

<script setup lang="ts">
definePageMeta({
  layout: 'custom'
})
</script>

레이아웃을 불러내야한다.

 

직접 불러내어 전체 레이아웃을 바꿀 수도 있다.

//app.vue

<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>

<template>
  <NuxtLayout :name="layout">
    <NuxtPage />
  </NuxtLayout>
</template>

클릭이벤트를 주어 레이아웃을 바꿀 수 있다.

<script setup lang="ts">
function enableCustomLayout () {
  setPageLayout('custom')
}
definePageMeta({
  layout: false,
});
</script>

<template>
  <div>
    <button @click="enableCustomLayout">Update layout</button>
  </div>
</template>

해당페이지에서만 바꿀수도 있다.

//pages/index.vue

<script setup lang="ts">
definePageMeta({
  layout: false,
})
</script>

<template>
  <div>
    <NuxtLayout name="custom">
      <template #header> Some header template content. </template>

      The rest of the page
    </NuxtLayout>
  </div>
</template>

//layouts/custom.vue

<template>
  <div>
    <header>
      <slot name="header">
        Default header content
      </slot>
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>

3.  Pages

pages 관련 내용(https://nuxt.com/docs/guide/directory-structure/pages)

pages/index.vue는 ' / ' Route 이다. 

Dynamic Route & Nested Routes

 Dynamic Route는 pages의 폴더 경로를 이용해 활용한다. NextJS의 Route를 생각하면 쉽게 이해할 수 있다.

Directory Structure (폴더구성)
-| pages/
---| index.vue  => "/"

---| login.vue  => "/login"

---| haha/
-----| index.vue  => "/haha"

---| usersprofile/
---| index.vue =>"/userprofile" index가 우선권이 있다.
-----| [id].vue  => "/userprofile/유저의 id혹은 고유번호 기타 등등"

---| board-[group]/
-----| [id].vue  => "/board-게시판의종류 혹은 기타/게시물 번호"

 

 아래의 사례로 라우팅에 대한 확인도 할 수 있다.

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

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

Page Metadata

페이지의 메타데이터를 활용하려면

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

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

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

그밖의 메타데이터 활용은 문서 참조.

Navigation

페이지간 이동은  <NuxtLink>를 사용한다.

<template>
  <NuxtLink to="/about">
    About page
  </NuxtLink>
</template>

 

또한 이벤트로는 navigateTo 함수를 사용해서 이용할수도 있다.

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

function navigate() {
  return navigateTo({
    path: "/search",
    query: {
      name: name.value,
      type: type.value,
    },
  });
}
</script>
<template>
  <div>
    <p>메인페이지 인디용~~</p>
    <button @click="navigate()">gogo</button>
  </div>
</template>
<style scoped>
h1 {
  color: red;
}
</style>

 

4. Components

Root폴더에 components폴더를 만든다. 또한 Nuxt에서는 따로 import하지 않고 바로 불러 올 수 있다.

// /components/KingBtn.vue

<template>
  <div>
    <button>im the king</button>
  </div>
</template>


// /pages/search.vue

<script setup lang="ts">
import 컴포넌트 이름 from '컴포넌트경로'
const show = ref(false);
</script>

<template>
  <div>
    <h1>search</h1>
    
    <LazyKingBtn v-if="show" />
    <!-- Component앞에 Lazy 접두사를 붙이면 컴포넌트가 지연 로딩이 되로록 설정할수 있다. 
    이를 통해 초기 로드시 컴포넌트를 불러오지 않고 컴포넌트가 실제로 필요한 시점에 
    비로소 로드되게끔 만드는 기능이다. -->
    
    <button @click="show = !show">King BTN</button>
    
    <component :is="import한 component이름"/>
  </div>
</template>

 

Client Component를 사용하기 위해서는 

[파일명.client.vue]로 파일이름을 지어주면 된다.

 

5. Error Page

에러페이지를 커스텀하기 위해서는 Root폴더에 error.vue를 만들어준다.

728x90

'VueJS > NUXT' 카테고리의 다른 글

Nuxt Kakao Map 연동  (0) 2024.08.25
Nuxt3__Data Fetch  (0) 2023.11.22

+ Recent posts