sortable.js 实现拖拽

sortable.js 是一个 JavaScript 库,用于在现代浏览器和触摸设备上重新排序拖放列表。

安装:

// 通过 npm安装
npm install sortablejs --save
	
// 在组件中导入
import Sortable from 'sortablejs'

使用:

Vue2 中使用Element-UIel-table 表格结合 sortable.js 实现表格拖拽。

点击编辑展示顺序,展示右侧的取消和保存按钮,此时表格可拖拽;点击取消按钮,隐藏右侧的取消和保存按钮,恢复之前表格的状态,此时表格不可拖拽;点击保存按钮,隐藏右侧的取消和保存按钮,将拖拽后的数据传给后端,此时表格不可拖拽。
在这里插入图片描述

<template>
	<div>
		<div style="display: flex;justify-content: space-between;">
	      <el-button @click="handleIsEditOrder">编辑展示顺序</el-button>
	      <div v-if="isEditOrder">
	        <el-button @click="handleCancelSort">取消</el-button>
	        <el-button type="primary" @click="handleSaveSort">保存</el-button>
	      </div>
   		</div>
		<el-table
	      v-if="isShowTable"
	      :data="tableData">
	      <el-table-column prop="showOrder" label="序号"></el-table-column>
	      <el-table-column prop="src" label="图片">
	        <template slot-scope="scope">
	          <img style="width: 50px; height: 50px" :src="scope.row.image"/>
	        </template>
	      </el-table-column>
	    </el-table>
	</div>
</template>

<script>
  import Sortable from 'sortablejs'
  export default {
    name: 'banner',
    data () {
      return {
        tableData: [],

		isShowTable: true,
        isEditOrder: false,
        sortable: null, // 拖拽对象
        sortData: [] // 拖拽数据
      }
    },
    mounted () {
    	this.getList()
    },
    methods: {
      // 获取列表
      async getList () {
        let res = await getBannerList()
        if (res.code === 0) {
          this.tableData = res.data
          this.initSortable()
        } 
      },
      // 初始化拖拽
      initSortable () {
        this.sortData = [...this.tableData]
        const el = document.querySelector('.el-table__body-wrapper tbody')
        //创建拖拽对象
        this.sortable = Sortable.create(el, {
          sort: this.isEditOrder, //是否可进行拖拽排序
          animation: 150,
          //拖拽完成,移除拖拽之前的位置上的元素,在拖拽之后的位置上添加拖拽元素
          onEnd: ({newIndex, oldIndex}) => {
            const val = this.sortData[oldIndex]
            this.sortData.splice(oldIndex, 1)
            this.sortData.splice(newIndex, 0, val)
          }
        })
      },
      // 编辑展示顺序
      handleIsEditOrder () {
        this.isEditOrder = true
        this.sortable.options.sort = true
      },
      // 取消拖拽顺序
      handleCancelSort () {
        // 使table先隐藏,再显示,table将恢复拖拽之前的样式
        this.isShowTable = false
        setTimeout(() => {
          this.isShowTable = true
          // 必须延时,否则重新初始化的sortable无法拖拽
          setTimeout(() => {
            this.isEditOrder = false
            this.sortable.options.sort = false
            this.initSortable()
          }, 100)
        }, 100)
      },
      // 保存拖拽顺序
      async handleSaveSort () {
       let res = await editBannerOrder(this.sortData)
       if (res.code === 0) {
          // 使table先隐藏,再显示,否则table将无法拖拽
          this.isShowTable = false
          setTimeout(() => {
            this.isShowTable = true
            this.isEditOrder = false
            this.getList()
          }, 100)
        }
      }
    }
  }
</script>