vue3表格使用拖拽排序

拖拽排序

实现效果

实现步骤

  1. 安装sortable.js库
  2. 使用的vue文件中引入 import Sortablejs from 'sortablejs'
  3. 在进入页面后创建sortable实例
  4. 在提交后端时可获取到排序后的最新table列表数据
    sortable.js文档

拖拽排序功能的完整代码

bash 复制代码
<template>
  <div style="height: 100%">
    <!-- ...省略其他代码... -->
    <div class="table-box" style="height: 100%;">
      <el-table class="sort-el-table" row-key="id" v-loading="loading" :data="tableList"
                style="flex: 1;margin-bottom: 20px;" height="100%">
                <!-- table中拖拽排序列 -->
        <el-table-column label="拖拽排序" fixed width="120px" align="center">
          <template #default="scope">
            <el-icon class="sort-icon" style="cursor: pointer">
              <Rank/>
            </el-icon>
          </template>
        </el-table-column>
        <el-table-column
            label="XXX"
            align="left"
            prop="deptName"
            width="220"
            show-overflow-tooltip
            fixed
        >
        </el-table-column>
        <el-table-column
            label="XXX"
            align="center"
            prop="dataAperture"
            width="120"
            fixed
        >
          <template #default="scope">
            <el-link type="primary" @click="handleDetail(scope.row)">
              <dict-tag :options="task_data_aperture" :value="scope.row.dataAperture"/>
            </el-link>
          </template>
        </el-table-column>
        <!-- 合并表头的效果 -->
        <el-table-column label="历史数据" align="center">
          <el-table-column
              v-for="(item, index) in historyRiskResultVOList"
              :key="index"
              :prop="'dataYear'"
              :label="item"
              align="center"
              width="100"
          >
            <template #header>
              <span>{{ item }}</span>
            </template>
            <template #default="scope">
              <dict-tag
                  :canClick="false"
                  :options="risk_model_result_level"
                  :value="getTableColumnData(scope.row, index)"
              />
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column label="本期数据" align="center">
          <el-table-column
              v-for="(item, index) in forecastRiskResultVOList"
              :key="index"
              :prop="'dataYear'"
              :label="item"
              align="center"
              width="100"
          >
            <template #header>
              <span>{{ item }}</span>
            </template>
            <template #default="scope">
              <dict-tag
                  :canClick="false"
                  :options="risk_model_result_level"
                  :value="getTableColumnData2(scope.row, index)"
              />
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column
            label="确认分析情况"
            align="center"
            prop="confirmDesc"
            show-overflow-tooltip
        />
      </el-table>
    </div>
    <div class="foot-btn">
      <el-button @click="backTo">上一步</el-button>
      <el-button type="primary" @click="nextStep">下一步</el-button>
    </div>
  </div>
</template>

<script setup>
import Sortablejs from 'sortablejs' //使用前先安装库

const {proxy} = getCurrentInstance();
const {task_data_aperture, risk_model_result_level} =
    proxy.useDict("task_data_aperture", "risk_model_result_level"); // 字典项
const emit = defineEmits(["backTo", "nextStep"]);

const historyRiskResultVOList = ref([])
const forecastRiskResultVOList = ref([])

const props = defineProps({
  taskObj: {
    type: Object,
    default: () => {
      return {}
    }
  },
  // 判断是否是编辑
  flag: {
    type: Boolean,
    default: false
  }
})

const loading = ref(false);
const tableList = ref([])

watch(() => props.taskObj, (v) => {
  // ...省略其他代码...
  nextTick(() => {
      // 进入页面后就开启表格拖拽排序
      const el = document.querySelector('.sort-el-table .el-table__body-wrapper  table tbody'); //  querySelector 方法选取页面上指定的元素。这里的选择器 '.sort-el-table .el-table__body-wrapper  table tbody' 定位到一个表格的 tbody 部分

      // 创建了一个 Sortable.js 实例,将 el 作为容器,用于拖拽排序
      Sortablejs.create(el, {
        animation: 150,
        ghostClass: 'blue-background-class',
        handle: '.sort-icon', // 指定了拖拽手柄的类名,如果需要点击某个图标拖拽的话需要吧那个图标的class写在这里
        onEnd: function (evt) { // 拖拽动作结束时触发
          let newIndex = evt.newIndex  // 排序后的索引位置
          let oldIndex = evt.oldIndex  // 排序前的索引位置
          if (newIndex !== oldIndex) { // 如果 newIndex 和 oldIndex 不相等,说明元素的位置发生了变化
            let currRow = tableList.value.splice(oldIndex, 1)[0]; // 从数组中移除原来位置的元素,并返回被移除的元素obj
            console.log("currRow:", currRow);
            tableList.value.splice(newIndex, 0, currRow); // 将被移除的该元素插入到新的位置
          }
        }
      })
    })
}, {immediate: true})


// 提交表格数据(根据表格顺序加index属性)
function nextStep() {
  tableList.value.forEach((item, index) => {
    item.index = index
  })
  console.log("当前的tableList:", tableList.value);
  return;
  emit('sortVal', tableList.value)
}
</script>
相关推荐
excel3 小时前
ES6 中函数的双重调用方式:fn() 与 fn\...``
前端
可乐爱宅着3 小时前
全栈框架next.js入手指南
前端·next.js
你的人类朋友5 小时前
什么是API签名?
前端·后端·安全
会豪7 小时前
Electron-Vite (一)快速构建桌面应用
前端
中微子7 小时前
React 执行阶段与渲染机制详解(基于 React 18+ 官方文档)
前端
唐某人丶7 小时前
教你如何用 JS 实现 Agent 系统(2)—— 开发 ReAct 版本的“深度搜索”
前端·人工智能·aigc
中微子7 小时前
深入剖析 useState产生的 setState的完整执行流程
前端
遂心_7 小时前
JavaScript 函数参数传递机制:一道经典面试题解析
前端·javascript
Gracemark7 小时前
高德地图-地图选择经纬度问题【使用输入提示-使用Autocomplete进行联想输入】(复盘)
vue.js
小徐_23337 小时前
uni-app vue3 也能使用 Echarts?Wot Starter 是这样做的!
前端·uni-app·echarts