Vue的v-for中列表项拖拽排序详细方法

Posted yccg990118

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue的v-for中列表项拖拽排序详细方法相关的知识,希望对你有一定的参考价值。

首先:html中,关键点是监听拖拽的三个阶段,即:dragstart/dragover/dragend,注意:要拖拽元素必须加上draggable="true"

<ul @dragstart="onDragStart"
@dragover="onDragOver"
@dragend="onDragEnd"
ref="taskListUl">
<li v-for="(subTask,index) in subTaskList"
draggable="true"
:id="subTask.id"
:key="subTask.id">
<el-row>
<el-col :lg="20">
<div class="main">
<el-row>
<el-col :span="3"><el-checkbox></el-checkbox></el-col>
<el-col :span="21" class="taskEdit" v-if="show.isShowEdit !== index" :title="subTask.name">subTask.name</el-col>
<el-col :span="21" v-else>
<el-row style="width: 300px;">
<el-form ref="taskEditForm" :model="subTask">
<el-col :span="14">
<el-input v-model="subTask.name" size="mini"
@keyup.enter.native="saveSubTask(‘subTaskForm‘,subTask);showEditTitle()"></el-input>
</el-col>
<el-col :span="10">
<el-button type="primary" style="font-size:12px;color:#fff;margin-left:4px;padding:5px 8px;border:0;"
size="mini" @click="saveSubTask(‘subTaskForm‘,subTask);handleTaskEdit()">保存</el-button>
<el-button style="font-size:12px;padding:5px 8px;border:0;" size="mini" @click="handleTaskEdit">取消</el-button>
</el-col>
</el-form>
</el-row>
</el-col>
</el-row>
</div>
<div class="icon1" v-if="show.isShowEdit !== index">
<el-button circle size="mini" @click="handleTaskEdit(index)"><i class="el-icon-edit"></i></el-button>
<el-button circle size="mini" @click="handleTaskDelete(index,subTask.id)"><i class="el-icon-delete"></i></el-button>
</div>
<div class="icon2">
<el-button circle size="mini"><i class="el-icon-s-finance"></i></el-button>
<el-button circle size="mini"><i class="el-icon-user"></i></el-button>
</div>
</el-col>
</el-row>
</li>
</ul>
其次,javascript
data()
return
  subTaskList: []
  
,
methods:
onDragStart(event)     //用于在拖拽开始时获取被拖拽元素
console.log("drag start")
this.draging=event.target;
console.log(this.draging);
,
onDragOver(event) //用于在拖拽过程中,获取拖拽元素经过的对象,以及对元素顺序做出调整
console.log(‘drag move‘);
this.target=event.path[5]; //li的位置
let targetTop=event.target.getBoundingClientRect().top;
let dragingTop=this.draging.getBoundingClientRect().top;
if (this.target.nodeName === "LI"&&this.target !== this.draging)
if (this.target)
if (this.target.animated)
return;


if(this._index(this.draging)<this._index(this.target))
this.target.parentNode.insertBefore(this.draging,this.target.nextSibling);
else
this.target.parentNode.insertBefore(this.draging, this.target);

this._anim(targetTop,this.target);
this._anim(dragingTop,this.draging);

,
_anim(startPos,dom) //用于重绘元素
let offset = startPos - dom.getBoundingClientRect().top;
dom.style.transition = "none";
dom.style.transform = `translateY($offsetpx)`;
//触发重绘
dom.offsetWidth;
dom.style.transition="transform .3s";
dom.style.transform=``;
clearTimeout(dom.animated);
dom.animated=setTimeout(()=>
dom.style.transition="";
dom.style.transform=``;
dom.animated=false;
,300)
,
onDragEnd(event) //结束后跟俊最终拖拽调整subTaskList数组

console.log(‘drag end‘);
//获取排序后的li节点数组
let currentNodes=Array.from(this.$refs.taskListUl.childNodes);
let newArr = [];
for(let i=0;i<currentNodes.length;i++)
for(let j=0;j<this.subTaskList.length;j++)
if(currentNodes[i].id == this.subTaskList[j].id)
newArr[i] = this.subTaskList[j];



this.subTaskList = newArr;
console.log(this.subTaskList);
,

_index(el) //用于根据元素id来获取对应元素的索引值
  let domData=Array.from(this.$refs.taskListUl.childNodes);
return domData.findIndex((currentValue,index,arr)=>
return el.id == currentValue.id;
);
,

以上是关于Vue的v-for中列表项拖拽排序详细方法的主要内容,如果未能解决你的问题,请参考以下文章

Vue El-Tree 拖拽排序方法(通用)

可拖拽排序的vue组件

vue拖拽排序插件vuedraggable的使用 附原生使用方法

Qt之QAbstractItemView视图项拖拽

vuedraggable拖拽任意组件并改变数据排序

jquery -- 拖拽排序分析