vue+element-ui+sortable.js實現表格行和列的拖拽


項目碰到一個需求是需要表格字段列進行順序拖拽,查過一些資料,中途也碰到了很多坑,實現方式如下:

封裝成公用組件操作

//父組件
<template>
   <div>
      <commonTable
        :loading="loading"
        :table-data="priceList"
        :table-header-tit="tableHeaderTit"
        :col-table-header-tit="colTableHeaderTit"
        @columnChange="columnChange"
      />
   </div>
</template>
<script>
import commonTable from '@/layout/components/common/commonTable.vue';
export default {
  name: 'Table',
  components: {
    commonTable
  },
  data() {
     tableHeaderTit: [],
     colTableHeaderTit:[],
     priceList:[],
     loading:false,
   },
   async mounted() {
      await this.initHandle();
   },
  methods:{
      initHandle(){
         //初始化調用獲取默認用戶表頭數據接口(這邊先用默認數據)
          this.tableHeaderTit=[
              { key: 1, label: '價單編號', field: 'priceCode'},
        { key: 2, label: '價單名稱', field: 'priceName' },
        { key: 3, label: '幣種', field: 'currency' },
        { key: 4, label: '業務類型', field: 'businessTypeName'},
        { key: 5, label: '審批狀態', field: 'auditStatusName'},
        { key: 6, label: '啟用日期', field: 'startDate' },
        { key: 7, label: '截止日期', field: 'endDate'}
          ];
          this.colTableHeaderTit=[
               { key: 1, label: '價單編號', field: 'priceCode'},
        { key: 2, label: '價單名稱', field: 'priceName' },
        { key: 3, label: '幣種', field: 'currency' },
        { key: 4, label: '業務類型', field: 'businessTypeName'},
        { key: 5, label: '審批狀態', field: 'auditStatusName'},
        { key: 6, label: '啟用日期', field: 'startDate' },
        { key: 7, label: '截止日期', field: 'endDate'}
          ]
      },
      columnChange(val) {
        // 列拖拽操作(改變一次排序遠程存儲一次用戶數據)
        //調保存用戶接口
      }
  }
}
</script>
//子組件 commonTable.vue
<template>
  <div class="commonTable">
    <el-table
          ref="table"
          v-loading="loading"
          style="width: 100%"
          class="table-wrap"
          :data="tableData"
          height="100%"
          row-key="item"
          stripe
          border
          header-cell-class-name="header-cell-color"
          @selection-change="handleSelectionChange"
        >
        <el-table-column
            type="selection"
            width="55"
          />
        <el-table-column v-for="(item, index) in colTableHeaderTit"
            class-name="allowDrag"
            :key="`colTableHeaderTit_${index}`"
            :prop="tableHeaderTit[index].field"
            :label="item.label" align="center"> 
        </el-table-column>
    </el-table>
  </div>
</template>
<script>
import Sortable from 'sortablejs' 
//需要下載sortablejs插件
//官方文檔地址:
https://github.com/SortableJS/Sortable export default { name:'commonTable', props:['tableData','tableHeaderTit','colTableHeaderTit','loading'], data() { return { } }, mounted() { this.rowDrop() //可拖拽行 this.columnDrop() //可拖拽列 }, methods: { //行拖拽 rowDrop() { const tbody = document.querySelector('.el-table__body-wrapper tbody') const _this = this Sortable.create(tbody, { onEnd({ newIndex, oldIndex }) { const currRow = _this.tableData.splice(oldIndex, 1)[0] _this.tableData.splice(newIndex, 0, currRow) } }) }, //列拖拽 columnDrop() { var _this = this; const wrapperTr = document.querySelector('.el-table__header-wrapper tr') this.sortable = Sortable.create(wrapperTr, { draggable: ".allowDrag",//允許拖拽元素(el-table-column上設置class-name為允許拖拽) animation: 180, delay: 0, //之前調用onEnd方法會出現表格DOM不更新以及表頭對不上的情況所以更換為onUpdate方法 //參考資料 https://www.jianshu.com/p/fd6eb408d8bd onUpdate:function(evt){ //修改items數據順序 var newIndex = evt.newIndex; var oldIndex = evt.oldIndex; const newItem = wrapperTr.children[newIndex]; const oldItem = wrapperTr.children[oldIndex]; // 先刪除移動的節點 wrapperTr.removeChild(newItem) // 再插入移動的節點到原有節點,還原了移動的操作 if(newIndex > oldIndex) { wrapperTr.insertBefore(newItem,oldItem) } else { wrapperTr.insertBefore(newItem,oldItem.nextSibling) } // 更新items數組(index-1是第一列有一個多選列不支持拖拽,否則會有排序錯亂的問題) var item = _this.tableHeaderTit.splice(oldIndex-1,1); _this.tableHeaderTit.splice(newIndex-1,0,item[0]); // 下一個tick就會走patch更新 //每次更新調取保存用戶接口 _this.$emit('columnChange',_this.tableHeaderTit) } }) } } } </script>

參考:https://www.jianshu.com/p/362f880d0bfd 

 

-----END

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM