antd vue版本添加table拖拽功能

antd vue3版本table没有找到行拖拽效果,这里自己简单实现一个,做成一个组件,到时候引用就好,后期如果table自带拖拽功能了,就不需要用这个了,这个是应急措施

拖拽组件

<template>
    <slot :customRow="customRow" :dataSource="dataSource"></slot>
</template>

<script lang="ts">
import type { Props } from "ant-design-vue/lib/form/useForm";
import { defineComponent, ref } from "vue";

export default defineComponent({
    props:{
        // 列表数据
        dataSource:Array,
        // 行的唯一值
        keyWords: String,
    },
    setup(props:Props,{emit}){
        const lastData = ref<any>([])
        const dragItem = ref<any>()
        const dragIndex = ref<any>()
        const targetArr = ref<any>([])
        const customRow = (record:any,index: any)=> {
            return {
                style: {
                    cursor: 'move'
                },
                // 鼠标移入
                onMouseenter: (event: any) => {
                    // 兼容IE
                    var ev = event || window.event;
                    if(ev && ev.target){
                        ev.target.draggable = true;
                    }
                },
                // 开始拖拽
                onDragstart: (event: Event | undefined) => {
                    // 兼容IE
                    var ev = event || window.event;
                    // 阻止冒泡
                    ev && ev.stopPropagation();
                    // 得到源目标数据
                    dragItem.value = record;
                    dragIndex.value = index;
                },
                // 拖动元素经过的元素
                onDragover: (event: any) => {
                    // 兼容 IE
                    var ev = event || window.event;
                    // 阻止默认行为*/
                    ev && ev.preventDefault();
                    // 拖拽在自己身上不需要做操作
                    if(index == dragIndex.value){
                        return;
                    }
                    // 在经过的元素的上面或者下面添加一条线
                    var nowLine = ev?.target.closest('tr.ant-table-row ');
                    if(!targetArr.value.includes(nowLine)){
                        targetArr.value.push(nowLine);
                    }
                    if(index>dragIndex.value){
                        if(!nowLine.classList.contains("afterLine")){
                            targetArr.value.forEach((item: any)=>{
                                item.classList.remove("beforLine");
                                item.classList.remove("afterLine");
                            })
                            nowLine.classList.add("afterLine");
                        }
                    } else {
                        if(!nowLine.classList.contains("beforLine")){
                            targetArr.value.forEach((item: any)=>{
                                item.classList.remove("beforLine");
                                item.classList.remove("afterLine");
                            })
                            nowLine.classList.add("beforLine");
                        }
                    }
                },
                // 鼠标松开
                onDrop: (event: Event | undefined) => {
                    // 兼容IE
                    var ev = event || window.event;
                    // 阻止冒泡
                    ev && ev.stopPropagation();
                    // 过滤出来源目标数据
                    let data2 = props.dataSource.filter((item: any)=>item[props.keyWords] === dragItem.value[props.keyWords]);
                    // 过滤出来除了源数据的数据
                    lastData.value = props.dataSource.filter((item: any)=>item[props.keyWords] !== dragItem.value[props.keyWords]);
                    // 将源数据插入到相应的数据中去
                    lastData.value.splice(index, 0,...data2);
                    console.log(lastData)
                    emit("update:dataSource",lastData.value);
                    targetArr.value.forEach((item: any)=>{
                        item.classList.remove("beforLine");
                        item.classList.remove("afterLine");
                    })
                    targetArr.value = [];
                }
            }
        }
        return {
            customRow,
        }
    }
})
</script>

如何使用

		// dataSource表示列表数据 keyWords表示可以取到当前行的唯一值的key
		<TableDragList v-model:dataSource="dataSource" :keyWords="'index'">
            <template v-slot="slotProps">
                <a-table 
                    :columns="columns" 
                    :customRow="slotProps.customRow" 
                    :dataSource="slotProps.dataSource" 
                    :pagination="pagination" 
                    :loading="loading" />
            </template>
        </TableDragList>

<style lang="less" scoped>
// 引用页面,或者全局(最好不要)设置一下这个虚线,拖拽时展示
    :deep(.beforLine) {
        .ant-table-cell{
            border-top: 1.1px dashed #1890ff !important;
        }
    }
    :deep(.afterLine) {
        .ant-table-cell {
            border-bottom: 1px dashed #1890ff !important;
        }
    }
<style>

如果需要控制某一些列不能被拖拽,需要双击或者鼠标选中复制内容可以如下操作

export const customCell = (record: any, index: any) => {
  return {
    style: {
      cursor: 'default',
    },
    // 鼠标移入
    onmouseenter: (event: any) => {
      // 兼容IE
      const ev = event || window.event;
      // 阻止冒泡
      ev && ev.stopPropagation();
      // 在经过的元素的上面或者下面添加一条线
      const nowRow = ev?.target?.closest('tr.ant-table-row ');
      nowRow.draggable = false;
      nowRow.style.cursor = 'default';
    },
    // 鼠标移出
    onmouseleave: (event: any) => {
      // 兼容IE
      const ev = event || window.event;
      // 阻止冒泡
      ev && ev.stopPropagation();
      // 在经过的元素的上面或者下面添加一条线
      const nowRow = ev?.target?.closest('tr.ant-table-row ');
      nowRow.draggable = true;
      nowRow.style.cursor = 'move';
    },
  };
};

如何使用

		// dataSource表示列表数据 keyWords表示可以取到当前行的唯一值的key
		<TableDragList v-model:dataSource="dataSource" :keyWords="'index'">
            <template v-slot="slotProps">
            <!-- :customCell="slotProps.customCell" 这里多一个props -->
                <a-table 
                    :columns="columns" 
                    :customRow="slotProps.customRow" 
                    :dataSource="slotProps.dataSource" 
                    :customCell="slotProps.customCell"
                    :pagination="pagination" 
                    :loading="loading" />
            </template>
        </TableDragList>
<script lang="ts" setup>
import { computed } from "vue";
import { customCell } from './../component/customCell';
const columns = computed(()=>[
	{
        title: '海报名称',
        dataIndex: 'name',
        key: 'name',
        width: 150,
        customCell: customCell, // 这里就是控制不让这一列拖拽
      },
      {
        title: '海报名称2号',
        dataIndex: 'name',
        key: 'name',
        width: 150, // 这一列就可以拖拽
      },
])
</script>

<style lang="less" scoped>
// 引用页面,或者全局(最好不要)设置一下这个虚线,拖拽时展示
    :deep(.beforLine) {
        .ant-table-cell{
            border-top: 1.1px dashed #1890ff !important;
        }
    }
    :deep(.afterLine) {
        .ant-table-cell {
            border-bottom: 1px dashed #1890ff !important;
        }
    }
<style>

效果

在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值