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>
相关推荐
啃火龙果的兔子几秒前
前端单元测试覆盖率工具有哪些,分别有什么优缺点
前端·单元测试
「、皓子~29 分钟前
后台管理系统的诞生 - 利用AI 1天完成整个后台管理系统的微服务后端+前端
前端·人工智能·微服务·小程序·go·ai编程·ai写作
就改了31 分钟前
Ajax——在OA系统提升性能的局部刷新
前端·javascript·ajax
凌冰_33 分钟前
Ajax 入门
前端·javascript·ajax
京东零售技术1 小时前
京东小程序JS API仓颉改造实践
前端
奋飛1 小时前
TypeScript系列:第六篇 - 编写高质量的TS类型
javascript·typescript·ts·declare·.d.ts
老A技术联盟1 小时前
从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析
前端·小程序
风铃喵游1 小时前
构建引擎: 打造小程序编译器
前端·小程序·架构
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)
前端·javascript·css·vue.js·前端框架·tailwindcss
小飞悟1 小时前
🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂
前端·javascript·设计