Vue3 使用ant design vue table组件实现自定义拖拽效果

代码运行效果图

 <template>
    <!-- 使用 customRow 方法设置行属性 -->
    <a-table
        :columns="staffColumnsSort"
        :dataSource="dataSource"
        :rowKey="record => record.staffId"
        :customRow="isSort ? customRow : null"
      >
        <!-- 拖拽icon -->
        <template #sort>
          <HolderOutlined />
        </template>
      </a-table>
</template>

<script>
import { ref } from 'vue'
import { staffColumnsSort} from '../../columns'
import { HolderOutlined } from '@ant-design/icons-vue'
export default{
    components: {
        HolderOutlined
      },
    setup(){
        const sourceObj = ref({}) //源对象
        const targetObj = ref({}) //目标对象
        const dataSource = ref([])//列表数据
        const sortInfo = ref([])//整理后发给后台的数组
        const isSort = ref(true)//是否在排序状态下
        //移除拖拽样式方法
        const removeStyle = () => {
          document.getElementsByClassName('ant-table-tbody').forEach(parent => {
                parent.getElementsByTagName('tr').forEach(child => {
                  child.removeAttribute('style')
                })
              })
        }
        const customRow = (record, index) => {
          return {
            style: {
              cursor: 'grab'
            },
            // 鼠标移入
            onMouseenter: event => {
            // 兼容IE
            var ev = event || window.event
            ev.target.draggable = true
            },
            // 开始拖拽
            onDragstart: event => {
              // 兼容IE
              var ev = event || window.event
              // 阻止冒泡
              ev.stopPropagation()
              // 得到源目标数据
              sourceObj.value = record
            },
            // 拖动元素经过的元素
            onDragover: event => {
              // 兼容 IE
              var ev = event || window.event
              // 阻止默认行为
              ev.preventDefault()
              console.log('ant-table-tbody元素个数', document.getElementsByClassName('ant-table-tbody'))
              console.log('拖动元素经过的元素索引', index)
              console.log(
            '表格子元素',
                document.getElementsByClassName('ant-table-tbody')[0].getElementsByTagName('tr')[index]
              )

               //表格右侧操作栏使用了fixed固定定位,因此ant-table-tbody有两个
          document.getElementsByClassName('ant-table-tbody').forEach(parent => {
            parent.getElementsByTagName('tr').forEach((item, i) => {
              if (i === index) {
                item.style.borderBottom = '2px solid #1677ff'
              } else {
                item.removeAttribute('style')
              }
            })
          })
        },
        // 鼠标松开
        onDrop: event => {
          // 兼容IE
          var ev = event || window.event
          // 阻止冒泡
          ev.stopPropagation()
          // 得到目标数据
          targetObj.value = record
          console.log('源数据', sourceObj.value)
          console.log('目标数据', targetObj.value)

          const newArr = dataSource.value

          const source = newArr.findIndex(item => item.staffId ==sourceObj.value.staffId)

          const target = newArr.findIndex(item => item.staffId ==targetObj.value.staffId)

          newArr.splice(source, 1)
          newArr.splice(target, 0, sourceObj.value)

          sortInfo.value = []
          newArr.forEach((item, index) => {
            sortInfo.value.push({
              staffId: item.staffId,
              sortIndex: index
            })
          })
          //松开鼠标后,清除底部拖拽样式
          removeStyle()
        },
        //鼠标移出
        onMouseleave: event => {
          // 兼容IE
          var ev = event || window.event
          //鼠标移出拖拽范围禁止拖拽并清除拖拽效果
          ev.target.draggable = false
          removeStyle()
         
        }
      }
    } 

    return {
        sourceObj, 
        targetObj,
        dataSource,
        sortInfo,
        removeStyle,
        customRow,
        isSort  
        }
    }
}
</script>

//columns.js
export const staffColumnsSort = [
  {
    title: '',
    dataIndex: 'sort',
    key: 'sort',
    align: 'left',
    width: 92,
    slots: { customRender: 'sort' }
  },
  {
    title: '序号',
    dataIndex: 'id1',
    key: 'id1',
    align: 'left',
    width: 117,
    slots: { customRender: 'id1' }
  },
  {
    title: '姓名',
    dataIndex: 'staffName',
    key: 'staffName',
    align: 'left',
    slots: { customRender: 'staffName' },
    ellipsis: true,
    width: 225
  },
  {
    title: '账号',
    dataIndex: 'mobile',
    key: 'mobile',
    align: 'left',
    ellipsis: true,
    slots: { customRender: 'mobile' },
    width: 174
  },
  {
    title: '所属组织',
    dataIndex: 'departmentName',
    key: 'departmentName',
    align: 'left',
    ellipsis: true,
    slots: { customRender: 'departmentName' },
    width: 172
  },
  {
    title: '指纹录入',
    dataIndex: 'fingerprintEntry',
    key: 'fingerprintEntry',
    align: 'left',
    width: 144,
    ellipsis: true,
    slots: { customRender: 'fingerprintEntry' }
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    align: 'left',
    slots: { customRender: 'action' },
    fixed: 'right',
    width: 124
  }
]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要将vue3右键菜单组件固定在arco.design表格内部,可以使用以下步骤: 1. 首先,在arco.design表格的外层包裹一个相对定位的 div 元素,这个 div 元素的高度和宽度要与表格相同。 2. 在这个 div 元素内部添加一个绝对定位的 div 元素,这个 div 元素的高度和宽度也要与表格相同。 3. 在这个绝对定位的 div 元素内部添加右键菜单组件。 4. 为这个绝对定位的 div 元素添加一个事件监听器,当鼠标右键点击时,显示右键菜单组件。 5. 在右键菜单组件的样式中,设置 position: fixed,这样右键菜单组件就可以固定在表格内部。 下面是一个示例代码: ```html <template> <div class="table-container"> <div class="table-wrapper"> <a-table> <!-- 表格内容 --> </a-table> <div class="context-menu" v-show="showMenu" @click="handleMenuClick"> <!-- 右键菜单内容 --> </div> </div> </div> </template> <script> export default { data() { return { showMenu: false, menuX: 0, menuY: 0 }; }, mounted() { document.addEventListener("contextmenu", this.handleContextMenu); document.addEventListener("click", this.handleMenuClose); }, beforeUnmount() { document.removeEventListener("contextmenu", this.handleContextMenu); document.removeEventListener("click", this.handleMenuClose); }, methods: { handleContextMenu(e) { e.preventDefault(); this.menuX = e.clientX; this.menuY = e.clientY; this.showMenu = true; }, handleMenuClose() { this.showMenu = false; }, handleMenuClick() { // 处理右键菜单的点击事件 } } }; </script> <style> .table-container { position: relative; height: 400px; /* 表格高度 */ width: 100%; /* 表格宽度 */ } .table-wrapper { position: absolute; top: 0; left: 0; height: 100%; width: 100%; } .context-menu { position: fixed; top: 0; left: 0; z-index: 999; /* 右键菜单的样式 */ } </style> ``` 在这个示例中,我们使用了一个外层的相对定位的 div 元素来包裹arco.design表格,然后在这个 div 元素内部添加了一个绝对定位的 div 元素,将右键菜单组件放在这个 div 元素内部。在右键菜单组件的样式中,设置了 position: fixed,这样右键菜单组件就可以固定在表格内部了。我们还为这个绝对定位的 div 元素添加了一个事件监听器,当鼠标右键点击时,显示右键菜单组件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值