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

将 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 指令方案是最简单实用的选择。

相关文章:

  • Linux云计算训练营笔记day11(Linux CentOS7)
  • 智慧赋能光伏运维——无人机巡检+地面监控双链路覆盖,打造光伏电站管理新标杆
  • Ansible模块——主机名设置和用户/用户组管理
  • 牛客网NC209794:使徒袭来
  • 一周快讯 | 银发文娱旅游一周新鲜事
  • 【愚公系列】《Manus极简入门》048-自然探险之旅:“户外活动规划师”
  • 深入理解 SPI 通信中的时钟极性与相位(CPOL 与 CPHA)
  • ARP 原理总结
  • 全新的开源监控工具CheckCle
  • C++学习:六个月从基础到就业——C++20:范围(Ranges)进阶
  • Supermemory:让大模型拥有“长效记忆“
  • 开源AI大模型等“神秘组合”,如何颠覆零售业数字化转型?
  • 统计客户端使用情况,使用es存储数据,实现去重以及计数
  • java中的Servlet4.x详解
  • GitHub排名第一的开源ERP项目:Odoo生产计划与执行的功能概述
  • Git初始化本地已有项目,并推送到远端Git仓库完整操作指南
  • Linux《自主Shell命令行解释器》
  • 昆仑通态MCGSpro,自定义配方功能
  • 用 CodeBuddy 搭建「MiniGoal 小目标打卡器」:一次流畅的 UniApp 开发体验
  • Grafana当前状态:SingleStat面板
  • 著名文学评论家、原伊犁师范学院院长吴孝成逝世
  • AG600“鲲龙”批生产首架机完成生产试飞
  • 香港特区政府强烈谴责美参议员恐吓国安人员
  • 阳光保险拟设立私募证券投资基金,总规模200亿元
  • 美联储官员:美国经济增速可能放缓,现行关税政策仍将导致物价上涨
  • 一涉嫌开设赌场的网上在逃人员在山东威海落网