보통 프론트 프로젝트에서 데이터 페칭을 할 때 axios 를 많이 사용하는데,
Nuxt3 에서는 useFetch 를 사용하는 것을 권장하고 있다.
https://nuxt.com/docs/getting-started/data-fetching#usefetch
그렇다면 useFetch 에 interceptor 를 추가하고자 하면 어떻게 할 수 있을까?https://github.com/nuxt/framework/discussions/5370
이미 많은 사람들이 해당 내용에 대해서 질문을 남겼다.
nuxt3 에서는 composables 하위의 파일들을 자동으로 가져오기 때문에,
composables/useCustomFetch.ts 를 만들어서 interceptor 를 만들어 보겠다.
import { UseFetchOptions } from "nuxt/dist/app/composables";
export default <T>(url: string, options?: UseFetchOptions<any, any, any>) => {
return useFetch<T>(url, {
...options,
onRequest({ request, options }) {
// 뭔가의 헤더 작업
// const headers = new Headers(options.headers);
// headers.set("Authorization", "Bearer Token");
// options.headers = headers;
},
onRequestError({ request, options, error }) {},
onResponse({ request, response, options }) {},
onResponseError({ request, response, options }) {},
});
};
일단 타입만 빼고 보면 간단하다.
useCustomFetch 는 useFetch 함수를 리턴하는데,
인자로 url, options 를 받아서 useFetch 에 그대로 넘겨 준다.
(여기서 useFetch 는 nuxt3 에서 auto import 를 해 오기 때문에 import 를 따로 안 해 주는 것이다.)
타입은, options 에는 UseFetchOptions 타입을 넣어줬는데,
요건 useFetch 를 따라서 들어가면 타입 설정된 것을 볼 수 있다.
나머지 제네릭 타입들도 넣어줄 수 있겠지만, 일단 any 로 해 두겠다.
<T> 제네릭을 추가해 준 이유는
useFetch 는 AsyncData 를 리턴하는데,
제네릭 안에 리턴 타입을 넣어 주기 위해서이다.
이런 식으로 데이터가 리턴되게 해 주기 위함이다.
사용하는 쪽에서
type User = {
name: string;
age: Number;
};
const data = useCustomFetch<User>("/test");
이런 식으로 호출하면 AsyncData 타입의 제네릭에 User 타입이 들어오게 되는데
이렇게 하면 무엇이 좋으냐...
AsyncData 타입을 타고 들어가면 아래처럼 정의 되어있다
export type AsyncData<Data, Error> = _AsyncData<Data, Error> & Promise<_AsyncData<Data, Error>>;
그렇다면 _AsyncData 는 무엇일까?
export interface _AsyncData<DataT, ErrorT> {
data: Ref<DataT | null>;
pending: Ref<boolean>;
refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>;
execute: (opts?: AsyncDataExecuteOptions) => Promise<void>;
error: Ref<ErrorT | null>;
}
data 가 Ref 데이터로 정의되어있다!!!!
Ref... 어디서 많이 보지 않았는가...!!!!!
그렇다. vue 의 ref 타입이다
https://vuejs.org/guide/typescript/composition-api.html#typing-ref
Promise 타입이기 때문에
await 호출 후 반환 값을 디스트럭처링 해서 data 를 가지고 온다면
_AsyncData 타입에서 data 의 타입을 Ref<T> 로 지정해 줬기 때문에,
data 타입이 Ref<T> 로 지정되는 것이다.
이것이 무엇에 좋느냐? typeError 를 체크할 수 있다는 것이다.
type User = {
name: string;
age: Number;
};
const user = ref("");
const { data } = await useCustomFetch<User>("/test");
user.value = data.value;
위처럼 기본값이 ""인 user 반응형 변수를 만들어 data 값을 넣으면 어떻게 될까. (두근두근)
거 개발자 양반 data의 타입은 User 인데 user 는 타입이 string 이지 않소 ("" 이 기본값이라 타입 추론으로 string 이 자동으로 들어감)
User 도 null 도 string 타입이 아니니 에러를 내뿜겠소
위처럼 typescript 의 장점인 typeError 를 내뿜는다.
const user: Ref<User | null> = ref(null);
const { data } = await useCustomFetch<User>("/test");
user.value = data.value;
해당 부분을 위처럼 Ref 타입으로 지정해 주면... 에러가 사라진다
'프론트 > Vue' 카테고리의 다른 글
Vue2, Vue3 에서 지원되는 라이브러리를 만들어 보자 (0) | 2024.04.20 |
---|---|
Nuxt(vue)에서 OAuth2 이용하기 (네이버, 카카오 로그인) (0) | 2022.09.19 |
[Nuxt] pwa cache 적용, version number 추가 (0) | 2022.02.06 |
[Vue] Auth 적용, axios default header 추가, plugin 추가 (0) | 2022.02.06 |
[vue] highcharts-vue, nuxt plugin 이용 (0) | 2022.02.06 |