使用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 },
效果(完美,只需要处理下删除列,让它自动换行)
缺陷
因为是交换元素,所以在移动到删除列的时候需要有个格子在那才能拖过去
猜你喜欢
- 16天前(希尔顿2021活动)希尔顿集团618盛夏大促开启
- 16天前(2020海丝之路文化博览会)2023海丝之路文化和旅游博览会开幕
- 16天前(中旅酒店 维景)中旅酒店首次AI数字人直播亮相南京维景
- 16天前(瑞士大酒店-自助餐怎么样)瑞意心旅,以食为先 瑞士酒店开启全新"瑞士早餐计划"
- 16天前(东北地区全域旅游)东北三省一区宣传贯彻研学旅游行业标准
- 16天前(重庆恐龙化石遗址)重庆黔江恐龙化石抢救性发掘新闻发布会举行
- 16天前(曼谷丽思卡尔顿公寓价格)在曼谷丽思卡尔顿酒店CALEŌ 邂逅鸡尾酒的浪漫艺术
- 16天前(澳涞坞是什么)从最美山庄到世界舞台:澳涞山庄见证世界十佳旅居城市评选
- 16天前(世茂海峡大厦多高)巴西地产高管齐聚厦门世茂海峡大厦 共探超高层建筑锻造经验
- 16天前(内蒙古交通旅游图)内蒙古着力提升交通与旅游服务水平
网友评论
- 搜索
- 最新文章
- (2020广州车展哈弗)你的猛龙 独一无二 哈弗猛龙广州车展闪耀登场
- (哈弗新能源suv2019款)智能科技颠覆出行体验 哈弗重塑新能源越野SUV价值认知
- (2021款全新哈弗h5自动四驱报价)新哈弗H5再赴保障之旅,无惧冰雪护航哈弗全民电四驱挑战赛
- (海南航空现况怎样)用一场直播找到市场扩张新渠道,海南航空做对了什么?
- (visa jcb 日本)优惠面面俱到 JCB信用卡邀您畅玩日本冰雪季
- (第三届“堡里有年味·回村过大年”民俗花灯会活动)第三届“堡里有年味·回村过大年”民俗花灯会活动
- (展示非遗魅力 长安启源助力铜梁龙舞出征)展示非遗魅力 长安启源助力铜梁龙舞出征
- (阿斯塔纳航空公司)阿斯塔纳航空机队飞机数量增至50架
- (北京香港航班动态查询)香港快运航空北京大兴新航线今日首航
- (我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉)我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉
- 热门文章