vue3+elment plus + sortable 实现table表格可拖拽排序

效果预览

table可拖拽

  1. 安装依赖
pnpm i sortablejs  
  1. 封装table组件
<template>
  <div class="tableBox cmt-16">
    <el-table
      :data="tableData"
      class="ELtable"
      :height="height"
      :width="width"
      stripe
      :header-cell-style="{ background: '#F3F3F4', color: '#323233' }"
      :row-key="
        (row) => {
          return row.id;
        } "
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="30" :reserve-selection="true" class-name="selected"></el-table-column>
      <el-table-column label="序号" type="index" align="center" class-name="selected" width="100"></el-table-column>
      <el-table-column
        v-for="(column, index) in tableColumns"
        :key="`col_${index}_${mykey}`"
        :label="column.label"
        :prop="column.prop"
        :index="index"
        :row-index="null"
        :sortable="true"
        :min-width="column.width ? column.width : 100"
        class-name="allow-drag"
      ></el-table-column>
    </el-table>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import Sortable from "sortablejs"; //http://www.sortablejs.com/options.html 配置项中文文档
// 表格数据

const props = defineProps({
  tableData: {
    type: [Array],
    defaule: [],
  },
  tableColumns: {
    type: [Array],
    defaule: [],
  },
  height: {
    type: [Number, String],
    default: "auto",
  },
  width: {
    type: [Number, String],
    default: "100%",
  },
});

const emits = defineEmits<{
  (event: "changeCol", data: Object): void;
  (event: "changeRow", data: Object): void;
}>();
onMounted(() => {
  rowDrop();
  columnDrop();
});
// 行拖拽
const rowDrop = () => {
  const tbody = document.querySelector(".ELtable tbody");
  Sortable.create(tbody, {
    animation: 150, //动画参数
    onEnd({ newIndex, oldIndex }) {
      // const currRow = tableData.value.splice(oldIndex, 1)[0]
      // tableData.value.splice(newIndex, 0, currRow)
      // 在此触发父组件中的方法
      emits("changeRow", { oldIndex: oldIndex, newIndex: newIndex });
    },
  });
};

// 列拖拽
const columnDrop = () => {
  const tbody = document.querySelector(".ELtable tr");
  Sortable.create(tbody, {
    animation: 180,
    delay: 10,
    filter: ".selected",  // 过滤器,给不需要进行拖动的元素加上此类名,该元素不能主动拖动,但是其他的可拖动的依然可以与该元素交换位置
    draggable: ".allow-drag", //允许拖拽的项目类名,没有该类名的元素主动被动都不能变换
    onEnd: (evt) => {
      setTimeout(() => {
        emits("changeCol", { oldIndex: evt.oldIndex, newIndex: evt.newIndex });
      }, 500);
    },
  });
};

//复选框发生变化时触发
const multipleSelection = ref([]);
const handleSelectionChange = (val) => {
  console.log(val, 666);
};
</script>

<style lang="scss" scoped>


</style>

  1. 父组件主要代码
<template>
</cusButton>
        <cusTable  :tableData="tableData" :tableColumns="tableColumns"
        @changeCol="changeCol"
        @changeRow="changeRow"
        ></cusTable>
</template>

<script setup lang="ts">
import { useRouter } from "vue-router";
import { ref } from "vue";
const router = useRouter();

// 表格数据
let tableData = reactive([
	{
		id: 1,
		name: '张三',
		age: 18,
	},
	{
		id: 2,
		name: '里斯',
		age: 11,
	},
	{
		id: 3,
		name: '饺5子',
		age: 13,
	},
	{
		id: 4,
		name: '饺子7',
		age: 13,
	},
	{
		id: 5,
		name: '饺子',
		age: 13,
	},
	{
		id: 6,
		name: '饺子7',
		age: 13,
	},
	{
		id: 7,
		name: '饺子',
		age: 13,
	},
	{
		id: 8,
		name: '饺子3',
		age: 13,
	},
	{
		id: 9,
		name: '饺子7',
		age: 13,
	},
	{
		id: 10,
		name: '饺子4',
		age: 13,
	},
	{
		id: 11,
		name: '饺子2',
		age: 13,
	},
	{
		id: 12,
		name: '饺子1',
		age: 13,
	},
]);
// 表格列数据
interface ColType {
  label:String,
  prop:String
}
let tableColumns :ColType[] = reactive([
	{ label: 'id', prop: 'id' },
	{ label: 'name', prop: 'name' },
	{ label: 'age', prop: 'age' },
]);

// 改变列排序
const changeCol = ({oldIndex ,newIndex})=>{
  const empty = 2;  // 跳过选择框和序号列,根据自己场景做一个变量
  const oldItem = tableColumns[oldIndex - empty]
  tableColumns.splice(oldIndex-empty, 1)
  tableColumns.splice(newIndex-empty, 0, oldItem)
}

// 改变行排序
const changeRow = ({oldIndex ,newIndex})=>{
   const currRow = tableData.splice(oldIndex, 1)[0]
      tableData.splice(newIndex, 0, currRow)
}
</script>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现拖拽功能可以使用 SortableJS 库,并结合 Element Plus 的表格组件和 Vue3 的响应式数据。 首先需要在项目中安装 SortableJS: ``` npm install sortablejs --save ``` 然后在需要使用的组件中引入 SortableJS 和 Element Plus 的表格组件: ```javascript import Sortable from 'sortablejs'; import { ElTable, ElTableColumn } from 'element-plus'; ``` 接着,在组件中定义表格数据和表格列,以及拖拽回调函数: ```javascript export default { data() { return { tableData: [ { name: 'John', age: 20, address: 'New York' }, { name: 'Tom', age: 25, address: 'London' }, { name: 'Lucy', age: 18, address: 'Paris' }, { name: 'Lily', age: 22, address: 'Tokyo' } ], tableColumns: [ { label: 'Name', prop: 'name' }, { label: 'Age', prop: 'age' }, { label: 'Address', prop: 'address' } ] }; }, mounted() { // 绑定拖拽回调函数 const el = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody'); Sortable.create(el, { animation: 150, onEnd: evt => { const { newIndex, oldIndex } = evt; const item = this.tableColumns.splice(oldIndex - 1, 1)[0]; this.tableColumns.splice(newIndex - 1, 0, item); } }); }, render() { return ( <ElTable ref="table" data={this.tableData}> {this.tableColumns.map(column => ( <ElTableColumn label={column.label} prop={column.prop}></ElTableColumn> ))} </ElTable> ); } }; ``` 这里使用 `Sortable.create` 方法创建一个拖拽对象,并且绑定了 `onEnd` 回调函数,当拖拽结束后,将表格列数组中的相应元素移动到新位置。 最后渲染表格时,使用 `map` 方法动态创建表格列。 这样就实现了列拖拽功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值