Vue3、el-table、sortablejs实现行拖动时出现的问题和解决方案

初始化

插件引入参考其他文章

<div class="header-set-main">
        <el-table
          :data="dictList"
          show-overflow-tooltip
          height="450"
          highlight-current-row
          ref="dictTable"
          :key="dictTableKey"
        >
          <el-table-column
            align="center"
            prop="name"
            label="数据类型"
            min-width="100"
          />
          <el-table-column
            align="center"
            prop="sort"
            label="排序"
            min-width="40"
          >
          </el-table-column>
        </el-table>
      </div>
/*
* 
*/
const rowDropInit = () => {
      Sortable.create(dictTable.value.$el.children[2].children[0].children[1], {
        animation: 150,
        delay: 0,
        onEnd: function (e) {
          const res = state.dictList.splice(e.oldIndex, 1)[0];
          state.dictList.splice(e.newIndex, 0, res);

          state.dictList.forEach((item, index) => {
            item.sort = index;
          });
        },
      });
    };

 onMounted(async () => {
      /*------------------
      * 异步加载table数据
      * ------------------
      */
      nextTick(() => {
        rowDropInit();
      });
    });

出现的问题

拖动后实际渲染的结果和table数据顺序不同,只要是因为虚拟dom和真实dom不同步

在这里插入图片描述
在这里插入图片描述

解决方案

给当前table绑定一个key值。当出现拖动事件即修改key值,强制整个table更新。但是需要在table更新后重新注册拖动功能

const rowDropInit = () => {
      Sortable.create(dictTable.value.$el.children[2].children[0].children[1], {
        animation: 150,
        delay: 0,
        onEnd: function (e) {
          const res = state.dictList.splice(e.oldIndex, 1)[0];
          state.dictList.splice(e.newIndex, 0, res);

          state.dictList.forEach((item, index) => {
            item.sort = index;
          });
          //通过更新el-table的key值来保证table排序的数据渲染正确。
          state.dictTableKey++;
        },
      });
    };
  
 /*
 * 监听table的key值,重新注册拖动功能
 */
 watch(
      () => state.dictTableKey,
      () => {
        nextTick(() => {
          rowDropInit();
        });
      }
    );

拖动后正确的排序结果:
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐