Table表格数据合并、拆分、单条与多条拖动

Sortable.js中文文档地址:链接:https://www.itxst.com/sortablejs/neuinffi.html

代码直接复制粘贴即可运行看效果图,关于使用请看注释 效果图:

拖动

安装:npm install sortablejs --save

具体实现代码如下:

 <template>
   <div>
     <div>
       <el-button style="margin-bottom: 5px;" @click="clickMerge" type="success">并组
       </el-button>
       <el-button style="margin-bottom: 5px;" @click="clickSplit" type="danger">拆分
       </el-button>
     </div>
     <el-table
       :data="dataList"
       border
       height="500"
       v-loading="dataListLoading"
       @select="select"
       @selection-change="selectionChangeHandle"
       :header-cell-style="{background:head_background_color}"
       ref="table2"
       class="right_tab"
       row-key="id"
       :paginationLayout="'prev, pager, next'"
       style="width: 100%;">
       <el-table-column
         type="selection"
         header-align="center"
         align="center"
         width="50">
       </el-table-column>
       <el-table-column
         prop="name"
         header-align="center"
         align="center"
         show-overflow-tooltip
         label="名称">
       </el-table-column>
       <el-table-column
         prop="age"
         header-align="center"
         align="center"
         show-overflow-tooltip
         label="年龄">
       </el-table-column>
     </el-table>
   </div>
</template>

<script>
  import Sortable from "sortablejs"
  export default {
    name: "index",
    data() {
      return {
        head_background_color: '#E9F1FF',
        dataList: [{ name: '张三', age: 18, id: 1 ,mergeId:''},
          { name: '小明', age: 19, id: 2,mergeId:'' },
          { name: '小红', age: 20, id: 3,mergeId:'' },
          { name: '赵四', age: 21, id: 4,mergeId:'' },
          { name: '李四', age: 21, id: 5,mergeId:'' },
          { name: '王五', age: 21, id: 6,mergeId:'' }],
        dataListLoading: false,
        selected: false,
        dataListSelections:[],
      }
    },
    //Sortable实例需要在mounted方法中初始化
    mounted(){
      this.$nextTick(() => {
        this.rowDrop()
      })
    },
    methods: {
      //判断勾选状态
      select(selection, row) {
        this.selected = selection.length && selection.indexOf(row) !== -1
      },
      //勾选数据
      selectionChangeHandle(val) {
        if (this.selected) {//选中
          let list = []
          val.forEach((item, index) => {
            this.dataList.forEach((v, k) => {
              if (item.mergeId === v.mergeId) {
                if (v.mergeId) {
                  list.push(v)
                } else {
                  list = val
                }
              }
            })
          })
          this.dataListSelections = this.arrDistinctByProp(list, 'id')

          if (list.length > 0) {
            list.forEach(row => {
              this.$refs.table2.toggleRowSelection(row, true);
            });
          }
        } else {
          this.dataListSelections = []
          this.$refs.table2.clearSelection();
        }
      },
      //数组去重
      arrDistinctByProp(arr, prop) {
        return arr.filter(function (item, index, self) {
          return self.findIndex(el => el[prop] == item[prop]) === index
        })
      },
      //行-拖拽
      rowDrop() {
        const tbody = document.querySelector('.right_tab .el-table__body-wrapper tbody')
        const _this = this
        Sortable.create(tbody, {
          scroll: true,                             //可滚动
          animation: 800,                           //拖拽时的过渡效果
          onEnd({from, to, newIndex, oldIndex}) {
            let backData = JSON.parse(JSON.stringify(_this.dataList))
            let oldList = []
            backData.forEach((item, index) => {
              if (backData[oldIndex].mergeId &&
                item.mergeId == backData[oldIndex].mergeId) {
                oldList.push(item)
              }
            })
            if (oldList.length > 0) {//多行拖动
              let delList = backData.filter(item => item.mergeId !== backData[oldIndex].mergeId)
              delList.splice(newIndex, 0, oldList)
              backData = delList.flat()

            } else {//单行拖动
              let idx = newIndex
              if (newIndex > oldIndex) {//下滑
                backData.forEach((item, index) => {
                  if (item.mergeId && item.mergeId == backData[newIndex].mergeId) {
                    idx = index
                  }
                })
              } else if (newIndex < oldIndex) {//上滑
                let ids = []
                backData.forEach((item, index) => {
                  if (item.mergeId && item.mergeId == backData[newIndex].mergeId) {
                    ids.push(index)
                  }
                })
                if(ids.length>0){
                  idx = ids[0]
                }else{
                  idx = newIndex 
                }
              }
              const currRow = backData.splice(oldIndex, 1)[0]
              backData.splice(idx, 0, currRow)
            }
            _this.dataList = []
            _this.$nextTick(function () {
              _this.dataList = JSON.parse(JSON.stringify(backData))     //更新moveListData顺序
            });
          },
        })
      },
      //并组
      clickMerge() {
        if (this.dataListSelections.length < 2) {
          this.$message({
            message: '请至少选择两条数据进行操作。',
            type: 'warning'
          })
          return false
        }
        let arr = []
        let mergeId = this.getUUID()
        this.dataListSelections.forEach((item, index) => {
          arr.push({...item, mergeId: mergeId})
        })
        arr.forEach((item, index) => {
          this.dataList.forEach((v, k) => {
            if (item.id === v.id) {
              this.dataList[k].mergeId = item.mergeId
            }
          })
        })
        this.dataList = this.mergeSort(this.dataList)
        this.dataListSelections = []
        this.$refs.table2.clearSelection();
      },
      //拆分
      clickSplit() {
        if (this.dataListSelections.length < 2) {
          this.$message({
            message: '请至少选择两条数据进行操作。',
            type: 'warning'
          })
          return false
        }
        let arr = []
        let mergeId = this.getUUID()
        this.dataListSelections.forEach((item, index) => {
          arr.push({...item, mergeId: mergeId})
        })
        arr.forEach((item, index) => {
          this.dataList.forEach((v, k) => {
            if (item.id === v.id) {
              this.dataList[k].mergeId = null
            }
          })
        })
        this.dataListSelections = []
        this.$refs.table2.clearSelection();
      },
      //将mergeId相同的数据排序在一起
      mergeSort(arr) {
        const tempIds = [],
          newArr = []
        for (const item of arr) {
          if (!tempIds.includes(item.mergeId)) {
            newArr.push(item)
            if (item.mergeId) {
              tempIds.push(item.mergeId)
            }
          } else {
            for (const ele of newArr.entries()) {
              if (ele[1].mergeId === item.mergeId) {
                newArr.splice(ele[0] + 1, 0, item)
                break
              }
            }
          }
        }
        return newArr
      },
      getUUID () {
		  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
		    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
		  })
	  },
    }
  }
</script>


注:最近使用到了多条拖拽,就想浅浅分享一波,可能写的不够好,欢迎大家踊跃交流。

更多推荐