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>

效果

在这里插入图片描述

### 如何在 Ant Design Table 组件中实现列拖拽功能 为了实现在 Ant Design 的 `Table` 组件中的列拖拽功能,可以采用第三方库如 `vue-draggable-resizable` 来辅助完成这一特性[^2]。 #### 安装依赖包 首先,在项目环境中安装所需的 npm 包: ```bash npm install vue-draggable-resizable@2.1.0 ``` #### 修改组件模板结构 接着修改包含表格的组件文件,引入必要的模块并调整 HTML 结构以便于后续操作。这里假设已经有一个基于 Vue3 和 TypeScript 构建的应用程序,并且集成了 Ant Design Vue 库[^1]。 #### 编写具体逻辑代码 下面是一个简单的例子展示如何集成上述提到的功能到 Ant Design 的 `Table` 组件里去: ```typescript <template> <a-table :columns="draggingColumns" :data-source="dataSource"> <!-- 自定义表头 --> <template #headerCell="{ column }"> <span v-if="column.key === 'name'">Name (Drag)</span> </template> <!-- 使用 draggable 属性使行可被拖动 --> <template #bodyCell="{ record, index, column }"> <td @mousedown="handleMouseDown(index)" style="cursor: move;" v-if="column.dataIndex === 'operation'" /> {{record[column.dataIndex]}} </template> </a-table> </template> <script lang="ts"> import { defineComponent, ref } from "vue"; // 导入 Draggable 插件用于处理拖放事件 import Sortable from 'sortablejs'; export default defineComponent({ setup() { const draggingColumns = [ { title: 'ID', dataIndex: 'id', key: 'id' }, { title: 'Name', dataIndex: 'name', key: 'name' }, { title: '', dataIndex: 'operation', key: 'operation' } ]; let dataSource = ref([ { id: 1, name: 'John Brown' }, { id: 2, name: 'Jim Green' }, { id: 3, name: 'Joe Black' } ]); function handleMouseDown(index:number){ // 初始化 Sortable.js 并绑定至对应的 DOM 节点上 new Sortable(document.querySelector('.ant-table-tbody'),{ onEnd({ newIndex, oldIndex }) { var targetRow = dataSource.value.splice(oldIndex, 1)[0]; dataSource.value.splice(newIndex, 0, targetRow); } }); } return { draggingColumns, dataSource, handleMouseDown }; } }); </script> ``` 此段代码展示了通过监听鼠标按下事件触发初始化 `Sortable.js` 实例的方式实现了对指定列的操作单元格进行拖拽排序的效果。需要注意的是实际应用时可能还需要考虑更多边界情况以及样式优化等问题[^5]。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值