• Vue + Element 表格拖拽排序、树形表格拖拽排序


    今天给大家分享一下表格(列表)及树形表格拖拽排序,树形表格排序的教程不多,可能还会有问题,我在这里详细给大家讲解一下,如果你有这样的需求或觉得有用,请给个关注或收藏一下吧,方便后期查看使用。

    安装sortablejs

    npm install sortablejs --save
    
    • 1

    在需要的页面引入

    import Sortable from 'sortablejs'
    
    • 1

    表格加上row-key="id"

    <el-table ref="table" row-key="id" :data="tableData" style="width: 100%">
      <el-table-column prop="date" label="日期" width="180">el-table-column>
      <el-table-column prop="name" label="姓名" width="180">el-table-column>
    el-table>
    
    • 1
    • 2
    • 3
    • 4

    数据

    data() {
      return {
        tableData: [{ // 写的示例,项目中接口获取
          id:7458963256145,
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          id:1256358945623,
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          id:7485968563232,
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          id:4230568745963,
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    表格排序(列表)

    mounted () {
      // 调用 table拖拽排序 (有可能不生效,最好等表格数据获取后在调用,或加个this.$nextTick方法)
      this.rowDrop()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    methods: {
        rowDrop() {
          const tbody = this.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
          Sortable.create(tbody , {
          	animation: 300,
          	onEnd: e => {
    	       	//e.oldIndex为拖动一行原来的位置,e.newIndex为拖动后新的位置
    	        const targetRow = this.tableData.splice(e.oldIndex, 1)[0];
    	        this.tableData.splice(e.newIndex, 0, targetRow);
    	        let dragId = this.tableData[e.newIndex].id;//拖动行的id
    	       	// 请求接口排序,后面具体需要什么参数,获取就行了,每个人需要不一样
    	        
    	   	 } 
          })
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    树形表格排序(树结构)

    树形表格排序实现原理:把树形的结构转为列表再进行拖拽,不转换的话,拖拽的位置是不对的,就出错了

    data() {
      return {
        tableData: [
        	{
        		id: 1,
        		name: 'AAA',
        		level: 1,
        		children: [
        			{
        				id: 2,
    		    		name: 'A-1',
    		    		level: 2
        			}
        		]
        	},
        	{
        		id: 3,
        		name: 'BBB',
        		level: 1,
        		children: []
        	}
        ],
        activeRows: [] // 转换为列表的数据
      }
    },
    mounted () {
    	this.rowDrop()
    },
    methods: {
     	// 将树数据转化为平铺数据
    	treeToTile (treeData, childKey = 'children') {
          const arr = []
          const expanded = data => {
            if (data && data.length > 0) {
              data.filter(d => d).forEach(e => {
                arr.push(e)
                expanded(e[childKey] || [])
              })
            }
          }
          expanded(treeData)
          return arr
        },
    	rowDrop() {
          const tbody = this.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
          Sortable.create(tbody , {
          	animation: 300,
          	onMove: () => {
          		this.activeRows = this.treeToTile(this.tableData) // 把树形的结构转为列表再进行拖拽
          	},
          	onEnd: e => {
    	       	//e.oldIndex为拖动一行原来的位置,e.newIndex为拖动后新的位置
    	       	if (e.oldIndex !== e.newIndex) { // 根据自己项目需求增添条件限制
    	       		const oldRow = this.activeRows[e.oldIndex] // 移动的那个元素
    	       		const newRow = this.activeRows[e.newIndex] // 新的元素
    	       		// 请求接口排序,根据后端要求填写参数
    		
    	       	}
    	   	 } 
          })
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    这里就使用了2个方法,还有其它方法,根据自己需求来使用

    方法介绍
    onAdd: function (evt) { // 拖拽时候添加有新的节点的时候发生该事件
    	console.log('onAdd.foo:', [evt.item, evt.from])
    },
    onUpdate: function (evt) { // 拖拽更新节点位置发生该事件
      	console.log('onUpdate.foo:', [evt.item, evt.from])
    },
    onRemove: function (evt) { // 删除拖拽节点的时候促发该事件
     	 console.log('onRemove.foo:', [evt.item, evt.from])
    },
    onStart: function (evt) { // 开始拖拽出发该函数
     	 console.log('onStart.foo:', [evt.item, evt.from])
    },
    onSort: function (evt) { // 发生排序发生该事件
      	console.log('onUpdate.foo:', [evt.item, evt.from])
    },
    onEnd ({ newIndex, oldIndex }) { // 结束拖拽
     	 let currRow = _this.tableData.splice(oldIndex, 1)[0]
     	 _this.tableData.splice(newIndex, 0, currRow)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注意点

    1.如果你的onEnd方法不是箭头函数,如下面这样,需要在上面定义一下this指向,不然会报错

    const _this = this
    Sortable.create(tbody , {
    	onEnd ({ oldIndex, newIndex }) {
    	
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.添加拖拽的方法,需要等表格数据获取到,不然有可能是空的tbody ,拖拽就不生效了。
    可以在await表格数据获取后,在调用rowDrop方法

    3.如果刷新了表格,会导致拖拽失效,需要重新添加拖拽方法this.rowDrop()

    4.如果刷新表格会导致页面刷新,滚动条就不在之前操作的位置,需要重新滚动页面,体验效果不好。解决方案就是需要记录滚动条位置,拖拽后刷新页面自动滚动到当前位置,下一篇会讲解记录滚动位置,请进入我的主页查看

    结语

    这些都是博主在项目中遇到的一些问题,如果大家在使用中有问题,请在评论区说一下吧

  • 相关阅读:
    notepad++用于编写c#语言默认语言为.cs格式
    【鸿蒙 HarmonyOS 4.0】路由router
    项目小结:使用Docker迁移服务到离线服务器
    shell变量
    Python 中的 Pandas(数据分析与处理)
    静态代理IP是什么?一文看懂静态代理IP
    vue 子组件向父组件传递参数 子传父
    C/C++:双向队列的实现
    Dockerfile
    java线程池
  • 原文地址:https://blog.csdn.net/weixin_43953518/article/details/126173824