반응형
회사(여긴 react) 다니면서도 딱히 사용하지 않았던 Suspense 였지만 쓰고 싶어졌다.
물론 Vue3 에서는 이미 구현되어있지만 내 프로젝트는 Vue2 이기 때문에 직접 구현했다.
Vue2 에서 Suspense 사용하기
const Suspense = Vue.extend({
name: 'Suspense',
data() {
return {
isPageLoading: false,
};
},
async created() {
this.isPageLoading = true;
const getPageData = (this.$parent as any).getPageData;
if (!getPageData) {
throw new Error('getPageData methods 가 존재하지 않습니다');
}
await getPageData();
this.isPageLoading = false;
},
render(createElement) {
return createElement('div', this.isPageLoading ? this.$slots.fallback : this.$slots.default);
},
});
여기서는 this.$parent 아래의 setup 을 찾아서 하지만 내가 했을 때는 setup 을 찾을 수가 없었고
복잡한 사정에 의해 컴포지션 api 를 사용하지 말아야하는 이유 때문에 위와 같이 구현했다.
getPageData > page 정보를 불러오는 데이터
isPageLoading > page 로딩 여부
에러처리는 각 컴포넌트의 getPageData 내부에서 하는 걸로 결정했다..
물론 에러바운더리 같은걸 만들면서 마음이 바뀔 수도 있지만..ㅎ
아무튼 위와 같이 구현하면
장점 : 쉽게 구현 가능, setup 안 써도 됨
단점 : 매 페이지마다 getPageData 정의 필요, 추후 vue3로 마이그레이션시 하나하나 찾아서 수정해야함
+) 추가
계속 PageLoader 를 import 하는게 귀찮았고.. 하다보니 에러처리도 해야겠어서
기본 에러치리와 기본 로더를 추가했다.
const Suspense = Vue.extend({
name: 'Suspense',
data() {
return {
isPageLoading: false,
isPageError: false,
};
},
async created() {
this.isPageLoading = true;
const getPageData = (this.$parent as any).getPageData;
const onPageError = (this.$parent as any).onPageError;
if (!getPageData) {
throw new Error('getPageData methods 가 존재하지 않습니다');
}
try {
await getPageData();
} catch (e) {
this.isPageError = true;
onPageError?.(e);
console.error(e);
} finally {
this.isPageLoading = false;
}
},
render(createElement) {
if (this.isPageError) {
return this.$slots.error ? createElement('div', this.$slots.error) : createElement(PageError);
}
if (this.isPageLoading) {
return this.$slots.loader
? createElement('div', this.$slots.fallback)
: createElement(PageLoader);
}
return createElement('div', this.$slots.default);
},
});
결과!!
내가 대충 만들었더니 못생기긴 했다ㅜ
반응형
'프로젝트 > 트러블슈팅' 카테고리의 다른 글
Next.js 빌드 결과물(청크 파일)의 원본 파일은 어떻게 찾는걸까? (0) | 2025.02.13 |
---|---|
Github Actions 중 브라우저 설치 이슈 (0) | 2024.04.25 |
Vue 에서 sweetAlert2 JS 라이브러리 사용하다 생긴 일(feat svg) (2) | 2023.11.11 |
ESLint: TypeError: this.libOptions.parse is not a function (0) | 2023.06.11 |
한 컴퓨터에서 깃헙 계정 여러개 사용하기 (0) | 2022.08.07 |