当前位置: 首页 > java >正文

将 Element UI 表格拖动功能提取为公共方法

为了在多个页面复用表格拖动功能,我们可以将其封装成以下两种形式的公共方法:

方案一:封装为 Vue 指令(推荐)

1. 创建指令文件 src/directives/tableDrag.js

import interact from 'interactjs';export default {inserted(el, binding) {const tableBody = el.querySelector('.el-table__body-wrapper');if (!tableBody) return;// 设置初始样式tableBody.style.cursor = 'grab';tableBody.style.userSelect = 'none';// 初始化交互interact(tableBody).draggable({modifiers: [interact.modifiers.restrictRect({restriction: 'parent'})],listeners: {start: () => {tableBody.style.cursor = 'grabbing';},move: (event) => {tableBody.scrollLeft -= event.dx * (binding.value?.damping || 1);},end: () => {tableBody.style.cursor = 'grab';}},inertia: binding.value?.inertia || true,autoScroll: binding.value?.autoScroll || true});},unbind(el) {const tableBody = el.querySelector('.el-table__body-wrapper');if (tableBody) {interact(tableBody).unset();}}
};

2. 全局注册指令 src/main.js

import tableDrag from '@/directives/tableDrag';Vue.directive('table-drag', tableDrag);

3. 在组件中使用

<template><el-tablev-table-drag="{ damping: 0.8, inertia: true }":data="tableData"style="width: max-content"border><!-- 表格列 --></el-table>
</template>

方案二:封装为混合 (Mixin)

1. 创建混入文件 src/mixins/tableDrag.js

import interact from 'interactjs';export default {methods: {initTableDrag(tableRef, options = {}) {const tableEl = this.$refs[tableRef]?.$el;if (!tableEl) return;const tableBody = tableEl.querySelector('.el-table__body-wrapper');if (!tableBody) return;// 设置样式tableBody.style.cursor = 'grab';tableBody.style.userSelect = 'none';// 初始化交互this.tableDragInteract = interact(tableBody).draggable({modifiers: [interact.modifiers.restrictRect({restriction: 'parent'})],listeners: {start: () => {tableBody.style.cursor = 'grabbing';},move: (event) => {tableBody.scrollLeft -= event.dx * (options.damping || 1);},end: () => {tableBody.style.cursor = 'grab';}},inertia: options.inertia !== false,autoScroll: options.autoScroll !== false});},destroyTableDrag(tableRef) {const tableEl = this.$refs[tableRef]?.$el;if (!tableEl) return;const tableBody = tableEl.querySelector('.el-table__body-wrapper');if (tableBody && this.tableDragInteract) {this.tableDragInteract.unset();}}},beforeDestroy() {if (this.tableDragInteract) {this.tableDragInteract.unset();}}
};

2. 在组件中使用

<template><el-tableref="myTable":data="tableData"style="width: max-content"border><!-- 表格列 --></el-table>
</template><script>
import tableDragMixin from '@/mixins/tableDrag';export default {mixins: [tableDragMixin],mounted() {this.initTableDrag('myTable', {damping: 0.7,inertia: true});}
};
</script>

方案三:封装为高阶组件

1. 创建高阶组件 src/components/DraggableTable.vue

<template><div class="table-container"><el-tableref="table"v-bind="$attrs"v-on="$listeners"style="width: max-content"><slot></slot></el-table></div>
</template><script>
import interact from 'interactjs';export default {name: 'DraggableTable',props: {damping: {type: Number,default: 1},inertia: {type: Boolean,default: true}},mounted() {this.initDrag();},beforeDestroy() {this.destroyDrag();},methods: {initDrag() {const tableBody = this.$refs.table?.$el.querySelector('.el-table__body-wrapper');if (!tableBody) return;tableBody.style.cursor = 'grab';tableBody.style.userSelect = 'none';this.interactInstance = interact(tableBody).draggable({modifiers: [interact.modifiers.restrictRect({restriction: 'parent'})],listeners: {start: () => {tableBody.style.cursor = 'grabbing';},move: (event) => {tableBody.scrollLeft -= event.dx * this.damping;},end: () => {tableBody.style.cursor = 'grab';}},inertia: this.inertia});},destroyDrag() {if (this.interactInstance) {this.interactInstance.unset();}}}
};
</script><style scoped>
.table-container {width: 100%;overflow: hidden;
}
</style>

2. 在组件中使用

<template><draggable-table:data="tableData":damping="0.8"border><el-table-column prop="date" label="日期" width="180"></el-table-column><!-- 其他列 --></draggable-table>
</template><script>
import DraggableTable from '@/components/DraggableTable';export default {components: {DraggableTable},data() {return {tableData: []}}
};
</script>

对比三种方案

方案优点缺点适用场景
Vue 指令使用简单,全局可用配置选项较少简单拖动需求
Mixin灵活性高,可配置性强需要在组件中调用方法需要不同配置的多表格场景
高阶组件封装彻底,使用最简洁需要修改现有表格组件结构新项目或可接受组件替换的场景

推荐按项目需求选择合适的方案,对于大多数项目,Vue 指令方案是最简单实用的选择。

http://www.xdnf.cn/news/7348.html

相关文章:

  • SpringBoot(二)--- SpringBoot基础(http协议、分层解耦)
  • HGDB中如何为表增加自增主键
  • 如何映射 MongoDB 的 _id 字段?
  • Java大厂面试实战:Spring Boot与微服务场景中的技术点解析
  • 4.6 sys模块
  • 线程池中任务队列满-如何把多余的任务存储到Redis中
  • python打卡第30天
  • 体育赛事直播App的架构设计与关键技术解析
  • JavaScript面试题之原型链详解
  • 多商户1.8.1版本前端问题优化集合指南
  • python:pymysql概念、基本操作和注入问题讲解
  • 嵌入式学习--江协51单片机day8
  • AI Agent开发第71课-一个完善的可落地企业AI Agent全架构
  • 博客系统功能测试
  • CI/CD 实践:实现可灰度、可监控、可回滚的现代部署体系
  • MySQL死锁:面试通关“三部曲”心法
  • 电子学会Python真题知识点总结与分析
  • Java高频面试之并发编程-18
  • C++17之std::launder函数
  • 代码随想录算法训练营第四十四天
  • 企业网站架构部署与优化 --web技术与nginx网站环境部署
  • uWSGI、IIS、Tomcat有啥区别?
  • Linux 内核等待机制详解:prepare_to_wait_exclusive 与 TASK_INTERRUPTIBLE
  • day 21 常见降维算法
  • R²AIN SUITE 亮相第九届智能工厂高峰论坛
  • 基于DolphinScheduler抽取通用EventBus组件:支持延迟与事件驱动
  • centos把jar包配置成服务并设置开机自启
  • 基于ac自动机的内容审核
  • PyTorch模型保存方式
  • C++ —— Lambda 表达式