先介绍下原生JS的drag事件:
需要手动开启draggable="true"
ondrag | 该事件在元素正在拖动时触发 ondrag 事件在元素或者选取的文本被拖动时触发。 提示: 链接和图片默认是可拖动的,不需要 draggable 属性。 |
|
ondragend | 该事件在用户完成元素的拖动时触发 |
|
ondragstart | 该事件在用户开始拖动元素时触发 |
|
ondragenter | 该事件在拖动的元素进入放置目标时触发 | ondragenter 事件在拖动的元素或选择的文本进入到有效的放置目标时触发。 ondragenter 和 ondragleave 事件可以帮助用户更好的理解可拖动元素进入和离开放置区域的过程。 你可以在可拖动元素进入和离开放置区域时设置不同的背景颜色。 |
ondragleave | 该事件在拖动元素离开放置目标时触发 | ondragleave 事件在可拖动的元素或选取的文本移出放置目标时执触发。 ondragenter 和 ondragleave 事件可以帮助用户更好的理解可拖动元素进入和离开放置区域的过程。 你可以在可拖动元素进入和离开放置区域时设置不同的背景颜色。 |
ondragover | 该事件在拖动元素在放置目标上时触发 | ondragover 事件在可拖动元素或选取的文本正在拖动到放置目标时触发。 默认情况下,数据/元素不能放置到其他元素中。 如果要实现改功能,我们需要防止元素的默认处理方法。我们可以通过调用 event.preventDefault() 方法来实现 ondragover 事件。 |
ondrop | 该事件在拖动元素放置在目标区域时触发 | ondrop 事件在可拖动元素或选取的文本放置在目标区域时触发。 |
需要注意拷贝重置数组,列表渲染的数组也要隔离开,不然一选择都会跟着变.
数据源于:https://blog.csdn.net/qq_36384657/article/details/128667410
全部源码:
<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>