반응형

0. 목적

-. div 배열로 만들어진 테이블에 폴딩 부분을 만들어보자.

-. 동일한 기능을 수행하는 jQuery를 쓰는 예제가 많고, 사실 그게 더 편하긴 한데... 이왕 vue 공부중이니 vue를 만져서 folding table을 만들어보자.

1. 현 상황

-. 이전 포스팅 이후 이래저래 하다보니, 현재 이러한 테이블을 만들어 둔 상태다.

-. 각 코인을 거래소별로 쫙 나열하다보니 가시성도 좋지 않고.. 원래 목적인 최고가 / 최저가 거래소를 한 눈에 픽해서 보기에 잘 들어오질 않는다. 이걸 조금 더 보기 편하게, 아래와 같이 폴딩 테이블을 만들어야 할 필요가 있다.

2. 그럼 어떻게 할까...

1) 예제찾기

-. 관련된 예제를 찾으니 javascript를 쓰거나 bootstrap을 쓴 예제가 있고, jQuery를 쓴 아주 간단한 서식도 있다. 근데 이왕 vue 공부를 하고있으니.. vue에서 해결을 해보고 싶어서 더 찾아보니, 역시나 뷰 예제가 있어서 그걸 사용하기로 했다.

<div id="app">
  <table>
    <template v-for="row in rows">
      <tr @click="toggle(row.id)" :class="{ opened: opened.includes(row.id) }">
        <td>{{ row.name }}</td>
        <td>{{ row.handle }}</td>
      </tr>
      <tr v-if="opened.includes(row.id)">
        <td colspan="2">ON!</td>
      </tr>
    </template>
  </table>
</div>

-. 위 코드에서는, @click 으로 toggle 함수를 발동시키고, 아래에 v-if 구문의 'include[]' 안에 해당 rowid가 들어있을 경우 행을 출력하는 아주 간단한 구조를 가진다.

2) 내 코드에 적용하기

-. 하지만, 나는 위의 코드를 동일하게 적용하기는 힘들다. 우선 난 데이터 전부를 출력하는 것이 아니고, 또한 최고/최저가 연산이 필요하다. 아래와 같은 시퀀스로 작업을 하려 한다.

3. 작업시작: folding table 만들기

1) 코인 시세를 하부 컴포넌트로 전달

-. 이 작업은 어렵지 않다. (사실 vue 작업 자체가 엄청 쉽다)

-. 나의 경우엔 dataJson이란 json 변수에 거래소: {ticker: 가격} 순으로 정렬을 해놨는데, 이걸 뽑아가기만 하면 된다.

  <CoinTableRow :pricelist="coinPrices(coinKey)"/>

    
 methods:{
    coinPrices (ticker) {
      var priceList = {};
      const exchangers = Object.keys(this.chartVal.dataJson);

      for (var i=0; i < exchangers.length; i++){
        priceList[exchangers[i]] = this.chartVal.dataJson[exchangers[i]][ticker];
      }

      return priceList;

    },
    }

-. 위와 같이 하부 컴포넌트 CoinTableRow를 정의하고, methods에 해당 변수 생성을 위한 함수를 만들어주면 끝.

-. CoinTableRow 내에는 pricelist를 props로 받고, 출력만 해주는 경우 아래와 같이 json object가 그대로 출력되는 것을 볼 수 있다.

<template>
    {{pricelist}}
</template>

<script>
// @ is an alias to /src

export default {
  name: 'CoinTableRow',
  props: {
    pricelist: Object
  },
  components: {
  }
}
</script>

2) 전달받은 데이터로 표 행 꾸미기

-. 이제 저 데이터를 잘 만져서 표 행을 만들어봐야지. 우선은 이전에 만든 단순 표 행을 다시 구현해본다. 세로(한 컴포넌트에서 전부 그린 테이블)와 폴딩 (하위 컴포넌트로 값을 전달한 테이블)이 동일한 결과를 보여주는 것을 확인할 수 있다. 이제 다음 단계로 가보자.

 

3) 최대/최소 찾아서 보여주기

-. 갭 + 최대최소 찾기는 너무 간단하니까 수식만

      priceMaxMin: function() {
        var exchangers = Object.keys(this.pricelist);
        var exchanger;
        var v;
        var max = {
            'exchanger': null,
            'price': null,
        }
        var min = {
            'exchanger': null,
            'price': null,
        }
        for (var i=0; i<exchangers.length; i++){
            exchanger = exchangers[i];
            if (this.pricelist[exchanger]===undefined) //currency key 없음 -> no coin info
            { 
                //pass
            }
            else{
                if (this.pricelist[exchanger]['currency']==='KRW') //korean won
                {
                    v = this.pricelist[exchanger]['v'];
                }else if (this.pricelist[exchanger]['currency']==='USD') //USDT
                {
                    v = this.pricelist[exchanger]['v']*this.KRWUSD;
                    console.log('calc: ', v)
                }

                //find max
                if (max['price'] < v)
                {
                    max['price'] = v;
                    max['exchanger'] = exchanger;
                } else if (max['price']===null)
                {
                    max['price'] = v;
                    max['exchanger'] = exchanger;
                }
                //find min
                if (min['price'] > v){
                    min['price'] = v;
                    min['exchanger'] = exchanger
                }else if (min['price']===null)
                {
                    min['price'] = v;
                    min['exchanger'] = exchanger;
                }
            }
                    
          }
          console.log(this.ticker, "max: ", max['price'], "  min: ", min['price'])

        var gap = {'gap': max['price'] - min['price'],
                   'ratio': parseFloat(max['price']) / parseFloat(min['price'])
                   };

        return {'gap': gap,
                'max': max, 
                'min': min};
      },

-. 그리고 간단하게 3개의 div를 만들어 갭 / 최대/ 최소값을 넣어주자.

    <div class="table-row-item coinprice" :id="'ratio-'+ticker">
        {{((priceMaxMin.gap.ratio-1)*100).toFixed(0)}}%
    </div>
    <div class="table-row-item coinprice" :id="'highest-'+ticker">
        {{priceMaxMin.max.price}} <br> {{priceMaxMin.max.exchanger}}
    </div>
    <div class="table-row-item coinprice" :id="'lowest-'+ticker">
        {{priceMaxMin.min.price}} <br> {{priceMaxMin.min.exchanger}}
    </div>

4) 펼쳐졌을 때의 표 만들기

-. 펼쳐졌을 상태의 표를 먼저 만들어보자.

5) 접기/열기 칸 (div) 클릭 시 toggle 만들기

-. vue는 @click="함수" 방식으로 클릭했을 때 vue 내의 parameter 변경이 가능하다. 해당 div에 'isTableFolding' 파라미터의 toggle 함수를 연결해주자.

    <div class="table-row-folding-button" @click="TableFolding">
        접기/열기
    </div>
    
      methods: {
      TableFolding () {
          if(this.isTableFolding){
              this.isTableFolding = false;
          }
          else {
              this.isTableFolding = true;
          }
      },

-. 그리고 열고/접힐 아래 세부 행에는 v-if 설정을 해준다.

        <div class="table-row" v-if="isTableFolding">
            <div v-for="(exchange, exchangeKey) in pricelist" 
            :key="exchangeKey" class="table-row-item coinprice" :id="'row-' + exchangeKey">
                {{FormatPrice(pricelist[exchangeKey])}} <br> {{exchangeKey}}
            </div>
        </div>

-. 열고/접히는것 성공 (스타일이 좀 엉망이네...)

6) css 조금 만져주면..

-. 요래 나온다.

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기