使用vuedraggable 对一个 二维列表 实现拖拽修改
vuedraggable实现座位布局拖拽修改
方案一
修改 end,和move,在move中获取移动的元素值,和目的地元素值,在end中交换这两个元素
局限
- 元素需要是唯一值,不能有重复的
因为每次只能获取到值,而不是元素的位置,这就导致需要遍历整个列表查询位置,很麻烦
- 在创建删除队列后,无法将元素拖到删除队列
实现
{{ row }}dragMoveHandler(evt, originalEvent) { this.moveStart = { element: evt.draggedContext.element, index: evt.draggedContext.index } this.moveEnd = { element: evt.relatedContext.element, index: evt.relatedContext.index } return false }, dragEndHandler(evt) { let relatedRow = -1, draggedRow = -1 /*start:查询元素*/ for (let i = 0; i < this.arrange.length; i++) { if (draggedRow !== -1 && relatedRow !== -1) break if (draggedRow === -1 && this.arrange[i][this.moveStart.index] === this.moveStart.element) { draggedRow = i } if (relatedRow === -1 && this.arrange[i][this.moveEnd.index] === this.moveEnd.element) { relatedRow = i } } /*end*/ /*start:交换对调的元素 更新矩阵*/ this.$set(this.arrange[draggedRow], this.moveStart.index, this.moveEnd.element) this.$set(this.arrange[relatedRow], this.moveEnd.index, this.moveStart.element) /*end*/ },
效果(为了导出的gif比较小,就去色了)
方案二
突然发现 可以在 vue-draggable标签里添加自定义标签,可以从move的to和from里面的$attrs拿到,这就好办了,以前那种方法就是因为不知道怎么获取移动开始元素和目的地元素的信息,才只能用全局搜索的方法定位,现在的话可以直接获取就好办多了
实现(代码写得很乱,能用就行,哈哈哈哈)
思路就是在vue-draggable 加属性用来标记属于哪个分组以及是哪一行,我用的divide表示分组,row表示是二维数组的哪一行
vue那里就是覆写move和end,move里面记录每次移动的参数,最后一次的参数就是目的地,end里面就是判断从那里移动到哪里,并执行移动
移动需要用this.$set或者是其他能出发更新的,比如数组的pop,push等方法,这里用的splice(arr,index,remove,...addItem),第一个参数的数组,第二个是操作位置,第三个是在这个位置往后要移除多少元素,后面的参数是移除后插入的元素
{{ row }}dragMoveHandler(evt, originalEvent) { let from = evt.from.__vue__.$attrs let to = evt.to.__vue__.$attrs if(from == null || to == null) return; this.moveFrom = { row: from.row, index: evt.draggedContext.index, divide: from.divide } this.moveTo = { row: to.row, index: evt.relatedContext.index, divide: to.divide } return false // 阻止默认的拖拽 }, dragEndHandler(evt) { // 非法移动判断 if (this.moveTo.divide === 'arrange' && this.moveTo.index == null) return // 禁止删除列交换拖动 if (this.moveFrom.divide === this.moveTo.divide === 'deleted') return let elementTo = this.getElement(this.moveTo.divide, this.moveTo.row, this.moveTo.index) let elementFrom = this.getElement(this.moveFrom.divide, this.moveFrom.row, this.moveFrom.index) // 从删除列拖到正常列 if (this.moveFrom.divide === 'deleted' && this.moveTo.divide === 'arrange') { // 只有拖到不为空的列才交换,不然是填充到这一列 if (elementTo > 0) { this.$set(this.arrangeDeleted, this.moveFrom.index, elementTo) } else { this.arrangeDeleted.splice(this.moveFrom.index, 1) } this.$set(this.arrange[this.moveTo.row], this.moveTo.index, elementFrom) } // 正常列拖动都是交换 if (this.moveFrom.divide === 'arrange' && this.moveTo.divide === 'arrange') { this.$set(this.arrange[this.moveFrom.row], this.moveFrom.index, elementTo) this.$set(this.arrange[this.moveTo.row], this.moveTo.index, elementFrom) } // 正常列拖到删除列 正常列填充-1,删除列添加元素 if (this.moveFrom.divide === 'arrange' && this.moveTo.divide === 'deleted') { this.arrangeDeleted.push(elementFrom) this.$set(this.arrange[this.moveFrom.row], this.moveFrom.index, -1) } }, getElement(divide, row, index) { if (divide === 'deleted') { return this.arrangeDeleted[index] } else if (divide === 'arrange') { return this.arrange[row][index] } return undefined },
效果(完美,只需要处理下删除列,让它自动换行)
缺陷
因为是交换元素,所以在移动到删除列的时候需要有个格子在那才能拖过去
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章