이 글은 사수 없는 주니어 프론트 개발자가 혼자서 구글링도 해보고 혼자 머리 싸매고 고민해서 겨우겨우 간신히 해결한 경험을 바탕으로 작성되었습니다.
나는 JAVA 국비 6개월 과정을 수료하고, 어쩌다보니 프론트 개발자로 취업을 하게 되었다. 입사한 회사(현 직장)에서 내가 맡은 서비스는 PHP+Vue.js로 개발 되어있고, 예전에 백엔드 개발자 분들이 프론트도 같이 만들어 백엔드와 프론트의 의존도가 매우 높고 중간중간 백엔드스러운 코드들이 많았다. 그리고 회사 특성상 팀 당 프론트 개발자가 한 명이라 사수 없이 대형 프로젝트의 프론트 전반을 맡게된 나 자신. 신규 프로젝트를 하면서 동적으로 테이블 행을 병합해야하는 과제에 직면하게 되는데....
{
table_data: [
{ created_at: '2020-01-01', data1: '', data2: '', data3: '' },
...
]
}
// template 영역
...
<table>
<thead>
<tr>
<th>날짜</th>
<th>데이터1</th>
<th>데이터2</th>
<th>데이터3</th>
</tr>
</thead>
<tbody>
<tr v-for="item in tableData">
<td class="dynamic"> {{ item.created_at }} </td>
<td> {{ item.data }} </td>
<td> {{ item.data }} </td>
<td> {{ item.data }} </td>
</tr>
</tbody>
</table>
...
// script 영역
...
updated () {
$(".dynamic").each(function () {
var rows = $(".dynamic:contains('" + $(this).text() + "')");
if (rows.length > 1) {
rows.eq(0).attr("rowspan", rows.length);
rows.not(":eq(0)").remove();
}
});
}
...
updated()
훅에 제이쿼리를 사용해 행을 병합했다.// template 영역
...
<table>
<thead>
<tr>
<th>날짜</th>
<th>데이터1</th>
<th>데이터2</th>
<th>데이터3</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableData">
<td
v-if="index == 0 || item.created_at === tableData[index-1].created_at"
:rowSpan="getRowSpan(tableData, item)"
>
{{ item.created_at }}
</td>
<td> {{ item.data }} </td>
<td> {{ item.data }} </td>
<td> {{ item.data }} </td>
</tr>
</tbody>
</table>
...
// script 영역 - methods
...
getRowSpan(arr, data) {
let rowSpan = 0;
arr.forEach(item => {
if(item.created_at == data.created_at) rowSpan++;
});
return rowSpan;
}
...
나의 사수이자 선생님인 구글을 통해 짠 코드지만 저 코드도 사실 완벽하지 않다. 반복문 안에 조건문이 있어 배열의 길이 개수만큼 조건문을 연산하기 때문에, 렌더링 시 성능저하가 생길 수도 있다. 때문에 api 호출해서 응답값을 받을 때 계산을 하는 것도 좋은 방법인 것 같다.