vuedraggable 을 이용한 table 순번 변경하기
props로 tabledData를 받아와 tableData를 cloneDeep 으로 객체 복사를 해주고 시작,
⛔ 주의할점 - vuedraggable의 기본 구조에 들어갈 template가 아닌 다른 template가 존재하면 제대로 된 값을 반환하지 못함, 데이터의 유무를 판단할 시에는 없는 데이터는 따로 빼서 분기처리해줘야함,
<SPageable
:table-data="cloneTableData"
:is-hide-pagination="isProgress"
@getTableData="
(page) => {
$emit('changePage', page);
}
"
>
<template #data="{ data }">
<table class="admin-table">
<thead>
<tr>
<th>순서</th>
<th>썸네일</th>
<th class="text-left">제목</th>
<th>상태</th>
<th>진행기간</th>
<th>수정 일시</th>
<th>노출 여부</th>
</tr>
</thead>
<tbody v-if="!data || !data[0]">
<tr>
<td colspan="7"><div>데이터가 없습니다.</div></td>
</tr>
</tbody>
<template v-if="cloneTableData.content && cloneTableData.content[0]">
<draggable
v-model="cloneTableData.content"
tag="tbody"
v-bind="dragOptions"
:disabled="!isProgress"
@change="changeDrag"
>
<tr v-for="(item, index) in data" :key="item.id" @click="onGoDetail(item.id)">
<td>
<div>{{ cloneTableData.startCount + index }}</div>
</td>
<td>
<div class="img">
<img :src="`${$store.state.BASE_URL}${item.pcImage?.savedFileName}`" :alt="`${item.pcImageAlt}`" />
</div>
</td>
<td>
<div class="text-left">{{ item.title }}</div>
</td>
<td>
<div>{{ getState(item.state) }}</div>
</td>
<td>
<div>
<p>{{ item.startDate }} ~</p>
<p>{{ item.endDate }}</p>
</div>
</td>
<td>
<div>{{ item.lastModifiedDate }}</div>
</td>
<td @click.stop>
<div>
<SToggle v-model="item.isEnabled" @input="onEnabled(item.id, item.isEnabled)">{{
item.isEnabled ? '노출' : '미노출'
}}</SToggle>
</div>
</td>
</tr>
</draggable>
</template>
</table>
</template>
</SPageable>
<script>
export default {
name: 'SiteList',
props: {
tableData: {
type: Object,
required: false,
default: () => null
}
},
data() {
return {
id: null,
titleText: '',
baseUrl: '',
emojiType: '',
searchText: '',
cloneTableData: cloneDeep(this.tableData),
isProgress: true,
isShowDisabled: false
};
},
</script>
<script>
watch: {
tableData: {
deep: true,
handler(newValue) {
this.cloneTableData = cloneDeep(newValue);
}
}
},
</script>
vuedraggable 의 moved: 배열 내에서 이동된 요소의 정보를 포함합니다.
newIndex: 이동된 요소의 현재 인덱스
oldIndex: 이동된 요소의 이전 인덱스
element: 이동된 요소
이벤트 속성으로 list Index 변경 확인 후 params으로 보내줌,
<draggable
v-model="cloneTableData.content"
tag="tbody"
v-bind="dragOptions"
:disabled="!isProgress"
@change="changeDrag"
>
<script>
async changeDrag({ moved }) {
const { newIndex, oldIndex } = moved;
console.log('바뀐data: ', moved.element);
console.log('newIndex: ', this.cloneTableData.content[newIndex]);
console.log('oldIndex: ', this.cloneTableData.content[oldIndex]);
const params = {
isProgress: this.isProgress,
isShowDisabled: this.isShowDisabled,
dragId: this.cloneTableData.content[newIndex].id,
dropId: this.cloneTableData.content[oldIndex].id
};
await this.$axios.$put(`/admin/popups/order`, null, { params });
},
</script>
이동 시에 아래로 내리는 로직은 정상 작동했지만 아래에서 위로 올리는 작업 시 제대로 작동하지 않는것을 발견했다. index 계산식 작성 후 변경해줌.
<script>
async changeDrag({ moved }) {
const { newIndex, oldIndex } = moved;
const diff = newIndex < oldIndex ? 1 : -1;
console.log(this.cloneTableData.content.map((x) => `${x.id}`).join(','));
const params = {
isProgress: this.isProgress,
isShowDisabled: this.isShowDisabled,
dragId: moved.element.id,
dropId: this.cloneTableData.content[newIndex + diff].id
};
await this.$axios.$put(`/admin/popups/order`, null, { params });
},
</script>