728x90
개요
프로젝트 소스 중 문자열을 가지고 화면을 그리던 레거시 소스를 발견하여 직접 DOM을 조작하지 않고 화면을 구성하도록 Vue.js를 입혀 3300라인을 900라인으로 줄였다. 해당 경험을 간단히 정리해보았다.
화면 요구 사항
- 상품 리스트의 각 상품 정보가 다르다.
- 상품 리스트에 있는 상품 상태에 따라 뱃지가 달라져야 한다.
- 상품 케이스에 따라 버튼 UI가 다르다.
변경 전 소스
script에서 각 상품별 정보를 DOM에 문자열을 직접 수정한다.
상품 리스트 소스 중 스크립트 일부
...
if(contentItem.linkCd == 'APP_MN_KD30'){
content += '<div class="topBar">'
var cnt = 0;
if(item.newLaunched == 1 && cnt <2){
content+= '<div class="monae_status new"></div>' //new
cnt++
}
if(item.todayLaunched == 1 && cnt <2){
content+= '<div class="monae_status today"></div>' //오늘오픈
cnt++
}
if(item.mdRcmndYn == 1 && cnt <2){
content+= '<div class="monae_status md"></div>' //MD추천
cnt++
}
if(item.almostDeadline == 1 && cnt <2) {
content+= '<div class="monae_status deadline"></div>' //마감임박
cnt++
}
if(item.almostAchived == 1 && cnt <2){
content+= '<div class="monae_status goal"></div>' //달성임박
cnt++
}
content+= '<div class="mn_performance">';
var mn_performance = parseInt(item.fundingAchivementRate);
if(isNaN(mn_performance)) mn_performance = 0;
content += (mn_performance >= 100) ? '<em class="red">' : '<em>'
content += mn_performance +'% </em><span>달성</span></div>'
content += '</div>'
}
생략 ...
변경 전 소스(js에서 template을 문자열로 관리할때)의 문제점
- 한 페이지 당 script 소스가 늘어나 코드 가독성이 떨어진다.
- 같은 UI에도 불구하고 타입별로 파일이 분리되어 변경점이 늘어나 확장성 및 유지보수 성이 떨어진다.
- 문자열로 관리되기 때문에 개발자 실수에 의해 휴먼에러가 발생해도 놓치지 쉽다.
변경할 사항
- 상품 리스트의 각 상품 정보가 다르다. -> Vue의 데이터 바인딩
- 상품 리스트에 있는 상품 상태에 따라 뱃지가 달라져야 한다. -> 뱃지를 컴포넌트로 분리
- 상품 케이스에 따라 버튼 UI가 다르다. -> Vue의 조건부 렌더링 이용
변경 후 소스
<script type="text/x-template" id="GoodsListTpl">
생략 ...
<Badge :data="item" /> <!-- 뱃지 컴포넌트 분리 -->
<div class="name">{{item.goodsNm}}</div> <!-- 상품명 -->
<template v-if="item.priceOrigin != '0'">
<div class="price">{{item.priceSaled.sizeComma()}}<em>원</em></div>
</template>
<template v-else>
<div class="price">상담접수 상품</div>
</template>
<img :src="data.goodsInfo.img" @error="replaceNoImage" > <!-- noImage -->
생략 ...
</script>
<script type="text/x-template" id="BadgeTpl">
<div class="tag">
<template v-if="data.status == 'deadline'">
<div class="tagImg"><img :src="$uiPath+'images/common/tag_prd_deadline.png?version='+$version" alt=""></div>
</template>
<template v-else-if="data.status == 'open'">
<div class="tagImg"><img :src="$uiPath+'images/common/tag_prd_open.png?version='+$version" alt=""></div>
</template>
<template v-else-if="data.status == 'today'">
<div class="tagImg"><img :src="$uiPath+'images/common/tag_today.png?version='+$version" alt=""></div>
</template>
<template v-else-if="data.status == 'closing'">
<div class="tagImg"><img :src="$uiPath+'images/common/tag_prd_deadline.png?version='+$version" alt=""></div>
</template>
<template v-else>
<div class="tagImg"><img :src="$uiPath+'images/common/tag_prd_ongoing.png?version='+$version" alt=""></div>
</template>
</div>
</script>
실제 코드와 예시 코드와 다를 수 있습니다.
Vue를 적용하여 얻는 성과
- 상품리스트 파일이 3300라인 되던 코드가 900라인으로 줄었다.
- template 관리가 용이해졌다. (직접 DOM을 조작하지 않고 화면 구성이 가능)
- 뱃지를 컴포넌트로 분리하여 변경 및 확장이 쉽다.
- 타입스크립트의 경우 컴파일 과정에서 에러를 잡아낼 수 있다.
감사합니다.
Vue component : https://v2.ko.vuejs.org/v2/guide/components.html
728x90
'개발 > Vue.js' 카테고리의 다른 글
[Vue.js] TypeError: Cannot read properties of undefined (reading '__ob__') 해결방법 (0) | 2022.10.27 |
---|---|
Vue Cli 4.x (Vue3)에서 vue-router 사용하기 (0) | 2021.08.13 |
Vue.js란? (0) | 2021.07.06 |
vue.$NextTick이란? (0) | 2021.07.04 |
댓글