본문 바로가기
개발/Vue.js

프로젝트에 Vue.js를 적용한 경험

by 방구쟁이 2023. 4. 3.
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을 문자열로 관리할때)의 문제점

  1. 한 페이지 당 script 소스가 늘어나 코드 가독성이 떨어진다.
  2. 같은 UI에도 불구하고 타입별로 파일이 분리되어 변경점이 늘어나 확장성 및 유지보수 성이 떨어진다.
  3. 문자열로 관리되기 때문에 개발자 실수에 의해 휴먼에러가 발생해도 놓치지 쉽다.

 

변경할 사항

  • 상품 리스트의 각 상품 정보가 다르다. -> 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를 적용하여 얻는 성과

  1. 상품리스트 파일이 3300라인 되던 코드가 900라인으로 줄었다.
  2. template 관리가 용이해졌다. (직접 DOM을 조작하지 않고 화면 구성이 가능)
  3. 뱃지를 컴포넌트로 분리하여 변경 및 확장이 쉽다.
  4. 타입스크립트의 경우 컴파일 과정에서 에러를 잡아낼 수 있다.

 

 

감사합니다.

Vue component : https://v2.ko.vuejs.org/v2/guide/components.html

728x90

댓글