先介绍下原生JS的drag事件:
需要注意拷贝重置数组,列表渲染的数组也要隔离开,不然一选择都会跟着变.
数据源于:blog.csdn.net/qq_36384657…
全部源码:
<template>
<div>
<div style="width=300px;float: left; margin-bottom: 10px;">
<el-button type="primary" @click="visible = true">字段配置</el-button>
</div>
<el-popover
:visible="visible"
placement="bottom"
trigger="click"
title="自定义展示列表"
width="200"
virtual-triggering>
<el-checkbox
style="width: 120px"
v-for="(item, index) in cloumns"
v-model="item.visible"
:key="item.prop"
:label="item.label"
:draggable="true"
@dragstart="dragStartFn(index)"
@dragenter="dragEnterFn($event, index)"
@dragover="dragoverFn($event, index)" />
<el-divider style="margin: 10px 0" />
<div style="width: 135px; margin: 0 auto">
<el-button @click="reset">重置</el-button>
<el-button type="primary" @click="confirm">确定</el-button>
</div>
</el-popover>
<div>
<el-table
:data="tableData"
style="width: 100%"
border
:tree-props="{ children: 'children' }"
ref="table">
<el-table-column
v-for="(item, index) in cloumnsCOM"
:prop="item.prop"
:label="item.label"
:key="index" />
</el-table>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onBeforeMount } from "vue";
//多选框绑定数据
const cloumns = ref([
{ label: "计划名称", prop: "planName", visible: true },
{ label: "编号", prop: "id", visible: true },
{ label: "计划开始日期", prop: "beginTimeP", visible: true },
{ label: "计划完成日期", prop: "endTimeP", visible: true },
{ label: "实际开始日期", prop: "beginTimeS", visible: true },
{ label: "实际完成日期", prop: "endTimeS", visible: true },
{ label: "状态", prop: "status", visible: false },
{ label: "逾期状态", prop: "delayStatus", visible: false },
{ label: "备注", prop: "remark", visible: false },
]);
const tableData = ref([
{
id: "001",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
children: [
{
id: "00101",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00102",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00103",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00104",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
],
},
{
id: "002",
planName: "uuuu",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
children: [
{
id: "00201",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00202",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
],
},
{
id: "003",
planName: "yyyy",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
children: [
{
id: "00301",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00302",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
],
},
{
id: "004",
planName: "xxxx",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
children: [
{
id: "00401",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
{
id: "00402",
planName: "ffff",
beginTimeP: "2022-02-03",
endTimeP: "2022-02-03",
beginTimeS: "2022-02-03",
endTimeS: "2022-02-03",
},
],
},
]);
// 重置数据
const reCloumns = ref([]);
//列表渲染数据深拷贝
const tempCloumns = ref([]);
const cloumnsCOM = computed(() => {
return (tempCloumns.value as any).filter((item) => item.visible);
});
onBeforeMount(() => {
tempCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
reCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
});
const visible = ref(false);
// 拖动
const dragIndex = ref(0);
const enterIndex = ref(0);
const dragStartFn = (index: number) => {
dragIndex.value = index;
};
const dragEnterFn = (e: any, index: number) => {
e.preventDefault();
enterIndex.value = index;
const source = cloumns.value[dragIndex.value];
cloumns.value.splice(dragIndex.value, 1);
cloumns.value.splice(index, 0, source);
dragIndex.value = index;
};
const dragoverFn = (e: any, index: number) => {
e.preventDefault();
};
const confirm = () => {
tempCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
visible.value = false;
};
const reset = () => {
cloumns.value = JSON.parse(JSON.stringify(reCloumns.value));
tempCloumns.value = JSON.parse(JSON.stringify(reCloumns.value));
visible.value = false;
};
</script>