el-table 嵌套表格 拖拽的展开行bug解决方案

近日遇到一个需求,涉及到实现一个嵌套el-table自定义拖拽排序。看了一圈,发现挺多还是有bug,并没有比较好的办法,自己用Sortable.js 摸索解决。

首先贴一下html代码(额,很常规的业务代码):

<el-table
      :data="runData"
      ref="runTable"
      row-key="random"
      class="outTable"
      style="width: 100%"
    >
      <el-table-column type="expand">
        <template slot-scope="scope">
          <div class="sub-table">
            <el-table
              :data="scope.row.modular_lst"
              size="mini"
              border
              row-key="m_name"
              :class="'innerTable' + scope.$index"
            >
              <el-table-column prop="m_id" label="模块id">el-table-column>
              <el-table-column prop="m_name" label="模块名称">el-table-column>
            el-table>
          div>
        template>
      el-table-column>
      <el-table-column label="所属小组">
        <template slot-scope="scope">
          <span>{{ scope.row.group_name }}span>
        template>
      el-table-column>
      <el-table-column label="脚本模板">
        <template slot-scope="scope">
          <span>{{ scope.row.template_name }}span>
        template>
      el-table-column>
      <el-table-column label="状态">
        <template slot-scope="scope">
          <span :style="'color:' + orderMap[scope.row.state].color">
            {{ orderMap[scope.row.state].label }}
          span>
        template>
      el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <div class="edit-btn">
            <div
              v-if="
                ['2', '3', '4', '5'].includes(packageStatus) &&
                noHistory &&
                preFinish
              "
            >
              <el-button
                type="success"
                size="mini"
                :disabled="!['0'].includes(scope.row.state) || !isAllPublish"
                @click="goOnline(scope.$index)"
              >
                上线
              el-button>
              <el-button
                type="primary"
                size="mini"
                @click="editGroupTmpStatus(scope.$index, '0')"
              >
                重置状态
              el-button>
            div>
            <div v-if="['0'].includes(packageStatus) && noHistory">
              <el-button
                type="primary"
                size="mini"
                @click="addModulePre(1, null, scope.row, scope.$index)"
              >
                编辑
              el-button>
              <el-button
                type="danger"
                size="mini"
                @click="deleteTmpRow(scope.$index)"
              >
                删除
              el-button>
            div>

            <el-button
              type="primary"
              size="mini"
              @click="goHistory(scope.row.log_id)"
              v-if="scope.row.log_id !== ''"
            >
              日志
            el-button>
          div>
        template>
      el-table-column>
    el-table>

这里需要注意,给外层表格加上个class!且保证row-key唯一性。
el-table 嵌套表格 拖拽的展开行bug解决方案_第1张图片
我们看一下控制台元素信息,会发现展开的内容其实是一行元素 tr 。
而我们要实现的可拖拽效果,正是要在外表格的tbody下,去拖拽每行 tr元素。我们会发现数据元素行会带有class为el-table__row,可以用它来做标识拖拽元素。

贴一下主要函数Vue代码:

import Sortable from 'sortablejs';
。。。。。。
//行拖拽
rowDrop() {
    const tbody = document.querySelector('.outTable tbody');
    const _this = this;
    Sortable.create(tbody, {
        draggable: '.el-table__row',
        onChoose(e) {
            // console.log(e);
        },
        onStart(e) {
            // console.log(e);
			_this.$refs.runTable.toggleRowExpansion(_this.runData[e.oldDraggableIndex], false);
        },
        onEnd(e) {
            // console.log(e);
            // 不能用 oldIndex 和 newIndex ,嵌套表格会有 bug !!!
            const currRow = _this.runData.splice(e.oldDraggableIndex, 1)[0];
            _this.runData.splice(e.newDraggableIndex, 0, currRow);
        }
    });
},

首先定义可拖拽区域为:外层表格下的 tbody ,const tbody = document.querySelector(‘.outTable tbody’); 用Sortable创建拖拽对象,填写对应参数。

– draggable属性标识可拖拽的元素,填写我们刚才说的表格数据行class,‘.el-table__row’,这里如果不写这个参数,那么展开的那行也可拖拽了。

– onStart() 函数,表示开始时,我们需要把此时要拖拽的行的展开行收起,不然拖拽后的两个展开行会错位!

– onEnd() 函数,表示拖拽结束,两元素位置互换时。不能用 e.oldIndex 和 e.newIndex(这是元素的新旧位置,以表格行算,会把展开行也算进去) ,嵌套表格会有 bug !!需要用e.oldDraggableIndex和e.newDraggableIndex(这是可拖拽元素的新旧位置,以拖拽元素行算,不会把展开行算进去),具体对比可以自己实践打印 e 对比一下。

el-table嵌套表格拖拽

你可能感兴趣的:(开发小记,bug,vue.js,前端)