Sortable 拖拽行 跨表格拖拽

538 阅读1分钟

Sortable 拖拽行 跨表格拖拽

大家使用Sortable的时候,会遇到跨表格,行拖拽,数据错乱视图错乱的情况,这里就参考了一下大佬的代码

原文链接 juejin.cn/post/714641…

为了大家方便使用,我就直接贴上代码了

1.npm下载

    npm i sortablejs -S

2.import导入

    import Sortable from "sortablejs";

3.templatep片段

因为我这里的tableData是循环出来的,所以请自行删减

template片段

    <template v-for="item in attrInfoList.childAgList">
              <div class="draggable" :key="item.agId">
                <el-table
                  id="maintable"
                  :header-cell-class-name="cellClass"
                  :ref="attrInfoList.agName + '_' + item.agName"
                  :data="item.childAttrList"
                  :key="item.agId"
                  tooltip-effect="dark"
                  :row-key="undatetablekey"
                  border
                  style="width: 100%"
                  :row-class-name="tableRowClassName"
                  header-row-class-name="tableTitle"
                  @select="multipleSelectionChange"
                  @select-all="
                    (selection) => {
                      item.forEach((i) => {
                        i.isNeedSend = !!selection.length;
                      });
                    }
                  "
                  @row-click="
                    (row) => {
                      if (!inEdit) {
                        return;
                      }
                      let tableRef = Array.isArray($refs[attrInfoList.agName + '_' + item.agName])
                        ? $refs[attrInfoList.agName + '_' + item.agName][0]
                        : $refs[attrInfoList.agName + '_' + item.agName];
                      tableRef.toggleRowSelection(row);
                      row.isNeedSend = true;
                    }
                  "
                >
                  <el-table-column type="selection" :selectable="selectable" width="100" :key="tablekey"> </el-table-column>
                  <el-table-column align="left" prop="attrName" :label="item.agName" width="140" :key="tablekey"></el-table-column>
                  <el-table-column align="left" prop="item.usageRate" label="Probability of occurrence" width="220" :key="tablekey">
                    <template slot-scope="{ row }">
                      <span>{{ row.usageRate }} %</span>
                    </template>
                  </el-table-column>

                  <el-table-column align="center" prop="display" label="Display" width="220" :key="tablekey">
                    <template slot-scope="scope">
                      <el-select
                        v-show="selectValue"
                        v-model="scope.row.display"
                        placeholder="Necessary"
                        @change="handchangleSelect($event, scope.row)"
                        popper-class="eloption"
                        :popper-append-to-body="true"
                        style="display: block"
                        value-key="id"
                      >
                        <template v-for="(item, index) in options1">
                          <el-option :key="index" :label="item.label" :value="item.label"></el-option>
                        </template>
                      </el-select>
                      <span v-show="!selectValue">{{ scope.row.display }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column align="center" prop="required" label="If required" width="220" :key="tablekey">
                    <template slot-scope="required">
                      <el-select
                        v-show="selectValue"
                        v-model="required.row.required"
                        placeholder="Confirm quality"
                        @change="handchangleSelectrequi($event, required.row)"
                        value-key="attrId"
                        popper-class="eloption"
                        :popper-append-to-body="true"
                      >
                        <template v-for="(item, index) in options2">
                          <el-option :key="index" :label="item.label" :value="item.label"> </el-option>
                        </template>
                      </el-select>
                      <span v-show="!selectValue">{{ required.row.required }}</span>
                    </template>
                  </el-table-column>

                  <el-table-column header-align="center" align="left" prop="attrDataType" label="Field type" width="154" :key="tablekey">
                  </el-table-column>
                  <el-table-column header-align="center" align="center" prop="unit" label="Units" :key="tablekey"> </el-table-column>
                </el-table>
              </div>
            </template>

4.methods方法

data() {
    return {
     undatetablekey(row) {
        return row.attrId;
      },
    }
}
mounted() {
    this.tablekey = Math.random();
    // this.undatetablekey = Math.random();
  },
methods:{
     dragSort(list) {
      if (list) {
        list.forEach((i) => {
          // table层级的遍历
          i.childAgList.forEach((j) => {
            let tableRef = this.$refs[i.agName + "_" + j.agName] ? this.$refs[i.agName + "_" + j.agName][0] : this.$refs[i.agName + "_" + j.agName];
            tableRef.clearSelection();
            let el = tableRef.$el.querySelector(".el-table__body > tbody");
            this.sortTableArr.push(
              Sortable.create(el, {
                disabled: this.dragSortdisabled,
                animation: 250, //动画
                dragClass: "dragClass", //设置拖拽样式类名
                ghostClass: "ghostClass", //设置拖拽停靠样式类名
                chosenClass: "chosenClass", //设置选中样式类名
                multiDrag: true, // Enable multi-drag
                selectedClass: "selected", // The class applied to the selected items
                fallbackTolerance: 3, // So that we can select items on mobile
                forceFallback: true,
                group: {
                  name: "itxst.com",
                  pull: true,
                  put: true,
                },
                swapThreshold: 0.65,
                clone: function (elToClone) {
                  const clone = elToClone.cloneNode(true);
                  clone.classList.add("test");
                  return clone;
                },
                onChoose: (evt) => {
                  //初次进入
                  this.pullIndex = evt.oldIndex;
                  this.unMatchedList = j.childAttrList;
                },
                onAdd: (evt) => {
                  //evt.newIndex 移入到新数组的下标
                  //pullIndex 原数组拖拽元素的下标
                  // this.dataList = j.childAttrList;
                  // //当第二个表格为空时
                  this.tablesort = true;
                  if (!j.childAttrList) {
                    j.childAttrList = [];
                    j.childAttrList.splice(evt.newIndex, 0, this.unMatchedList[this.pullIndex]);
                  } else {
                    j.childAttrList.splice(evt.newIndex, 0, this.unMatchedList[this.pullIndex]);
                  }
                },
                onEnd: (evt) => {
                  if (!this.tablesort) {
                    const oldIndex = evt.oldIndex;
                    const newIndex = evt.newIndex;
                    const temp = j.childAttrList[oldIndex];
                    if (oldIndex < newIndex) {
                      // 向下移动调整顺序
                      for (let i = oldIndex; i < newIndex; i++) {
                        j.childAttrList[i] = j.childAttrList[i + 1];
                      }
                    } else if (oldIndex > newIndex) {
                      // 向上移动时调整顺序
                      for (let i = oldIndex; i > newIndex; i--) {
                        j.childAttrList[i] = j.childAttrList[i - 1];
                      }
                    }
                    j.childAttrList[newIndex] = temp;
                  }
                },
                onUpdate: (/**Event*/ evt) => {
                  // if (!this.tablesort) {
                  //   if (evt.newIndex !== evt.oldIndex) {
                  //     const currRow = j.childAttrList.splice(evt.oldIndex, 1)[0];
                  //     j.childAttrList.splice(evt.newIndex, 0, currRow); //数据互换位置
                  //     // j.childAttrList = j.childAttrList;
                  //     // this.$nextTick(() => {
                  //     //   // j.childAttrList = j.childAttrList;
                  //     //   this.dragSort(); // 为了解决element兼容问题这里必须在调用一次
                  //     //   //sortVolunteer 不然会出现乱序,不是element不用这些步骤。
                  //     // });
                  //   }
                  // }
                },
                onMove: (evt) => {},
                onRemove: (evt) => {
                  if (this.tablesort) {
                    j.childAttrList.splice(this.pullIndex, 1);
                  }
                },
              })
            );
          });
        });
      }
    },
    saveConfig(){
     this.dragSortdisabled = !this.dragSortdisabled;
      this.sortTableArr.forEach((item) => {
        let state = item.option("disabled"); // get
        item.option("disabled", !state); // set
      });
    }
  }