Project

[Vue] 상품 필터 구현하기 (feat. Typescript, ToastUI Chart)

 

 

☞ NuxtJS로 Typescript로 작성이 가능한 VueJS 애플리케이션을 만든 후 프로젝트를 진행하였습니다.

 

쇼핑몰에 상품이 많아 필터를 사용해서 효과적으로 상품을 찾아주는 기능을 구현해보았습니다.

 

- 상품 목록 헤더를 클릭 해 정렬 가능

- 페이지네이션

- 한 테이블에 나올 수 있는 테이블 갯수

- 필터 기능 (판매가, 판매원가, 이름, 상품 등록일)

- 필터에 맞게 만들어주는 Chart 기능 ( Toast UI Chart 사용)

- 모바일 화면에 맞춘, 반응형 css

 

먼저, TypeScript를 이용해 VueJS 애플리케이션을 만들어본 적이 처음이었기 때문에 TypeScript에 대한 공부가 필요했었습니다.  그래서 Youtube와 인프런 강의를 참조하며 기본적인 기능들을 다뤄봤습니다. 

또한 아래 Nuxt Typescript에도 설명히 자세히 나와있기 때문에 참고하면 좋습니다.

https://typescript.nuxtjs.org/

 

Nuxt TypeScript

 

typescript.nuxtjs.org

Nuxt Component에는 OptionAPI, Composition API, Class API 중 하나의 API를 선택해 기본적인 템플리 구조를 만들어야 하는데, 저는 인프런에 나와있는 강의와 똑같은 방식으로 Class API를 선택해 vue-property-decorator를 이용해 컴포넌트들을 만들어봤습니다.

https://github.com/kaorun343/vue-property-decorator

 

kaorun343/vue-property-decorator

Vue.js and Property Decorator. Contribute to kaorun343/vue-property-decorator development by creating an account on GitHub.

github.com

또한 중앙 저장소의 역할을 할 수 있는 Vuex를 사용해 Store를 만들어 데이터 저장소를 만들었습니다. 이때도 똑같이 vuex-module-decorator를 이용해 Store를 만들어보았습니다.

https://github.com/championswimmer/vuex-module-decorators

 

championswimmer/vuex-module-decorators

TypeScript/ES7 Decorators to create Vuex modules declaratively - championswimmer/vuex-module-decorators

github.com

필터에 맞게 차트를 만들어야하는데, TostUI Chart를 이용해 만들 계획이였습니다. 하지만, ToastUI Chart에 따라 만들기에는 VueJS 문법에 맞게 나오지 않아 따라하기 힘들었습니다. 다행이도 Git에 VueJS에 맞는 형식으로 만든 toast-ui/vue-chart가 있어 손쉽게 만들 수 있었습니다.

https://github.com/nhn/toast-ui.vue-chart

 

nhn/toast-ui.vue-chart

Toast UI Chart for Vue. Contribute to nhn/toast-ui.vue-chart development by creating an account on GitHub.

github.com

처리하기 어려웠던 것들 : 

1. window is not defined

NuxtJS에서는 애플리케이션 모드를 결정 할 수 있습니다. 'spa' 와 'universal' 모드를 나눌 수 있었는데, spa 모드란 client-side-rendering만 지원하는 모드이고, universal 모드는 server-side-rendering, client-side-rendering 둘 다 지원을 하는 모드입니다. 

차트를 만들때 그리고 Local Storage를 이용해 로컬 저장소에 필터 내용을 저장시켜 새로고침을 해도 데이터를 유지시켜주는 기능을 만들 때, window is not defined라는 에러를 계속 볼 수 있었습니다. 

구글링을 한 후에 universal 모드이기 때문에 server-side에는 작동을 하지 않는 window에 에러가 발생했다는 것을 알 수 있었습니다. 이를 해결하기 위해 2가지 해결책이 있었는데, universal 모드에서 spa 모드로 바꾸는 것과 window가 있는 부분에 if(process.browser)의 조건을 달아주어 클라이언트 측에서만 import를 해줄 수 있었습니다. 

이 때, universal를 spa로 바꾸면 build가 되지 않기 때문에 if(process.browser)를 사용해 처리해줬습니다.

https://ko.nuxtjs.org/faq/window-document-undefined/

 

window 혹은 document가 undefined

Nuxt.js에서 window 혹은 document가 undefined인 경우라면?

ko.nuxtjs.org

2. property 'component' does not exist on type 'routeconfig'

 이 문제는 사소했지만, 사소했던 걸 알아내는게 어려웠었습니다. 구글링을 아무리해봐도 똑같은 명칭의 에러에 대한 글을 발견 할 수 없어 확신 할 수 없었고, 갑자기 나온 에러였기 때문에 처리하기 까다로웠습니다. 다행히도 stackoverflow에 비슷한 에러에 대한 처리와 같은 메커니즘으로 처리해 해결을 할 수 있었습니다. 발생 원인은 정말 간단하게도 Nuxt 버전을 업그레이드를 해주면 됐었습니다.

 

이외에도 TypeScript와 JavaScript 간의 호환성 문제, Decorator방식과 Option 방식간의 문제 등 많은 문제들이 있었습니다. 

 

TypeScript와 JavaScript 간의 호환성 문제

node-module에서 javascript파일로 처리를 해주면 typescript에서 에러가 나올 수 있는 경우가 있습니다. 하지만 node-module는 원격저장소에 저장되지 않기 떄문에 따로 처리를 할 수 없어, 그 에러부분에 @ts-ignore를 사용해 에러처리를 해줘 해결을 했었습니다.

 

Decorator방식과 Option 방식간의 문제

toast-ui/vue-chart에서 구현 예시가 Option 방식이었기 때문에 클래스 방식(decorator 방식)으로는 알아서 만들어야했었습니다(구글링을 해도 잘 안나왔었어요...ㅠㅠ). 다행히 많이 만지다보면 익숙해져 잘 바꿀 수 있었습니다. 예로 들어 차트에 option 속성의 변수를 만들 때, Option 방식에서는 괄호안에 집어넣으면 되지만, 클래스 방식으로는 인터페이스를 여러개 만들어 넣어주는 방식으로 해결했었습니다.

 interface Options {
    chart: Chart;
    series: OptionSeries;
  }

  interface Chart {
    width: number;
    height: number;
    title: string;
  }

  interface OptionSeries {
    showLegend: boolean;
    showLabel: boolean;
    labelAlign: string;
  }

 

배운점 : 

 처음으로 Javascript가 아닌 TypeScript를 사용해 봤는데, 확실히 요즘 많은 기업들에서 TypeScript를 JavaScript를 대신해 사용하는 이유를 알 것 같았습니다. 확실히 절제적이고, 더 제약적인 언어로서 협업에 확실히 좋은 것 같다고 느꼈습니다. 또한 Angular와는 다르게 Typescript를 선택적으로 호환할 수 있는 VueJS를 사용해보니 아직 많은 커뮤니티가 형성되어있지 않다는 것을 알 수 있었습니다. 다만, Typescript를 완벽하게 사용 할 수 있다면 JavaScript 커뮤니티만으로도 완벽히 기능들을 만들어 낼 수 있을 것 같다는 느낌이 들어 TypeScript를 더 공부하고 싶다는 확신을 얻게 되었었습니다.

 

☞ 영상 :

 

Commit 요약 (프로젝트를 private로 진행을 했기 때문에 commit 기록을 남김.)

 

commit 요약.docx
0.25MB

 

소스 코드 :

https://github.com/withseungryu/filteredTable

 

withseungryu/filteredTable

a table that can be filtered using VueJS with typescript - withseungryu/filteredTable

github.com

궁금하점이 있으시면 댓글 달아주세요!~

 

 

반응형