계발하는 개발자

[Vue + JS] 상품 정렬 기능 구현 - sort 메서드 본문

📌 Language/Javascript

[Vue + JS] 상품 정렬 기능 구현 - sort 메서드

dev_genie 2023. 9. 29. 01:45

쇼핑몰 사이트의 상품페이지를 보면 위와 같은 상품 정렬 기능을 볼 수 있다.

기능 구현 자체는 그렇게 어렵지 않았는데, 여러 이슈들이 있어서 나름의 의미있었던 기억으로 남는다.😅

(Ex. 상품 전체를 조회할 수 있는 '전체'라는 lnb 클릭후 상품 정렬 버튼(신상품순, 낮은가격순 등 )을 누르면

url 파라미터 3번째 인자값으로 받아오는 값이 데이터와 매치되지 않아서 에러가 발생한다.

그래서 이에 대한 에러 처리를 따로 해줘야 했고, 모바일 화면에서는 select option 요소를 통해 상품 정렬 기능을 수행하려고 했는데 option 요소에 별도로 이벤트를 걸 수가 없어서 그로인해 내가 직접 select 요소 비슷하게 html, js 코드를 다시 짜줘야 했다..)

일단 css를 제외한 구현 코드는 아래와 같다!

<!-- 상품정렬 탭 -->
<ul class="option-left">
    <li class="filter_option" @click.prevent="sortFn('new_prd')">
        <a href="#">신상품순</a>
    </li>
    <li class="filter_option" @click.prevent="sortFn('low_price')">
        <a href="#">낮은가격순</a>
    </li>
    <li class="filter_option" @click.prevent="sortFn('high_price')">
        <a href="#">높은가격순</a>
    </li>
    <li class="filter_option" @click.prevent="sortFn('review')">
        <a href="#">상품평순</a>
    </li>
</ul>

// 상품 정렬 함수 
sortFn(pm) {
    const arr = store.state.gnb[store.state.curUrl0].items[store.state.curUrl1][store.state.curUrl2];

    if (pm === 'review') {
        arr.sort(function(a,b){
            return b.review - a.review
        })
    }
    else if (pm === 'high_price') {
        arr.sort(function(a,b){
            return b.dprice - a.dprice
        })
    }
    else if (pm === 'low_price') {
        arr.sort(function(a,b){
            return a.dprice - b.dprice
        })
    }
    else if (pm === 'new_prd') {
        arr.sort(function(a,b){
            return b.idx - a.idx
        })
    }
},

 

store.state.curUrl0/ curUrl1 / curUrl2 값은 라우팅된 페이지 url 파라미터의 각 값을 참조한다.  

 

그리고 각각의 vuex curUrl0 값을 가지고 gnb > items 객체에 접근

curUrl1 > curUrl2 배열값에 sort 메서드를 돌리면 끝이다.

이렇게 하면 인자 a,b 값을 앞뒤로 서로 비교해서 오름차순, 내림차순 정렬을 할 수 있다.

'a-b' 형식의 비교 함수 : 배열이 오름차순으로 정렬(5,4,3,2,1...)
'b-a' 형식의 비교 함수 : 배열이 내림차순으로 정렬(1,2,3,4,5...)

* 한 번에 이해하기 쉽도록 1234오 오름차순 -> 낮은 것부터 정렬 !
a가 b보다 낮으니까 a-b 는 낮은 숫자를 앞에 보낸다는 거!! 이렇게 외웠던 것 같다 ㅎ

.filter_option 요소를 클릭하면 sortFn함수 파라미터로 인자값이 전달되는데
인자값에 따라 조건을 구분해 해당되는 객체값을 기준으로 오름차순 or 내림차순 코드를 분리해줬다.
switch case 문으로 쓰면 좀더 직관적인 형태가 되긴 하는데
코드 양이 좀더 길어져서 여기서는 그냥 if/else if 조건문을 사용했다.


이렇게 끝났다 하고 마지막 점검을 해보는데....

에러 뽷 !!

 

위에서 말했던 vuex curUrl2값이 제대로 바인딩이 안되어서 에러가 나는 거였단..

그래서 기존 함수를 async 함수로 만들고 에러 핸들링하는 구문을 추가!!

// 상품 정렬 함수 
    async sortFn(pm) {
        try {
            const arr = store.state.gnb[store.state.curUrl0].items[store.state.curUrl1][store.state.curUrl2];

            // lnb '전체' 클릭시 에러 핸들링
            if(store.state.curUrl2 === '전체') {
                throw new Error('curUrl2 카테고리 바인딩 없음')
            }

            if (pm === 'review') {
                arr.sort(function(a,b){
                    return b.review - a.review
                })
            }
            else if (pm === 'high_price') {
                arr.sort(function(a,b){
                    return b.dprice - a.dprice
                })
            }
            else if (pm === 'low_price') {
                arr.sort(function(a,b){
                    return a.dprice - b.dprice
                })
            }
            else if (pm === 'new_prd') {
                arr.sort(function(a,b){
                    return b.idx - a.idx
                })
            }
        }
        catch(error) {
            console.log(error)
            const allObj = store.state.gnb[store.state.curUrl0].items[store.state.curUrl1]

            for(let x in allObj) {
                const allCat = allObj[x];

                switch (pm) {
                    case 'review':
                        allCat.sort(function(a,b){
                            return b.review - a.review
                        });  
                        break;
                    case 'high_price':
                        allCat.sort(function(a,b){
                            return b.dprice - a.dprice
                        })
                        break;
                    case 'low_price':
                        allCat.sort(function(a,b){
                            return a.dprice - b.dprice
                        })
                        break;
                    case 'new_prd':
                        allCat.sort(function(a,b){
                            return b.idx - a.idx
                        })
                        break;
                }
            }
        }
    },

 

에러가 나면 준비해둔 메시지를 띄우고

그 안에서 또 비교정렬함수가 실행되도록 해줬다.

 

이제 전체탭 클릭후 상품정렬버튼을 선택해도 콘솔창에 표시만 될 뿐,

변경된 결과가 정상적으로 화면에 출력된다!

🧡 결과 화면 🧡

 

LIST
profile

dev_genie

@dev_genie

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!