您好,欢迎访问一九零五行业门户网

关于Vue拖拽组件的开发介绍

本文重点给大家介绍vue拖拽组件开发实例,拖拽的原理是手指在移动的过程中,实时改变元素的位置即top和left值,使元素随着手指的移动而移动。对实例代码感兴趣的朋友一起学习吧
为什么选择vue?
主要原因:对于前端开发来说,兼容性是我们必须要考虑的问题之一。我们的项目不需要兼容低版本浏览器。项目本身也是一个数据驱动型的。加之,vue本身具有以下主要特性:
•使用虚拟dom;
•轻量级框架;
•高效的数据绑定;
•灵活的组件系统;
•完整的开发生态链。
这就是我们为什么选择vue框架的一些原因。
为什么要封装成一个vue组件?
主要目的是可提高代码的复用性和可维护性。
•复用性:组件化后,一些样式和逻辑均通过配置参数的方式去差异化体现,所以参数的可配置性提高了组件的复用率和灵活性。
•可维护性:组件化后,组件内部的逻辑只对组件负责,外部的逻辑只通过配置参数适配,所以提高了代码的逻辑清晰度,可以快速定位代码出现问题的地方。
组件化搭建页面图示:
上图可看出,在vue中,所谓组件化搭建页面,简单来说,页面实际上是由一个个功能独立的组件搭建而成。这些组件之间可以组合、嵌套,最终形成了我们的页面。
组件构成
下面是一个完成的组件构成:
// 组件内模板// 组件内逻辑代码<script type="text/javascript"></script>// 组件内封装的样式<style lang="scss" scoped></style>
开发vue移动拖拽组件为例
拖拽原理
手指在移动的过程中,实时改变元素的位置即top和left值,使元素随着手指的移动而移动。
拖拽实现
•开始拖动时:获取到接触点相对于整个视图区的坐标clientx,clienty;获取元素距离视图上侧和左侧的距离 inittop,initleft;计算接触点距离元素上侧和左侧的距离 eltop = clienty - inittop, elleft = clientx - initleft;
•拖动过程中:通过 currtop = clienty - eltop, currleft = clientx - elleft实时获取元素距离视图上侧和左侧的距离值,并赋值给元素,使元素跟着手指的移动而动起来;
•拖动结束,定位元素。
vue中的实现
使用vue,最大的不同之处是我们几乎不去操作dom,要充分利用vue的数据驱动来实现拖拽功能。本例中,我们只需在垂直方向上拖动元素,所以只需考虑垂直方向的移动即可。
上图中,通过data中的draglist渲染拖拽区域列表,代码如下:
template:<p class="drag-title">拖拽可调整顺序</p><ul class="drag-list"> <li class="drag-item">{{item.txt}}</li></ul>script: export default {data() {return {draglist:null}},created() {this.draglist = [{isdrag: false,txt: '列表1',isshow: false}...]},}
假设我们将元素从位置1拖至位置3,本质上是数组的顺序发生了改变。这就有必要提一下vue的最大特性:数据驱动。
所谓的数据驱动就是当数据发生变化时,通过修改数据状态,使用户界面发生相应的改变,开发者不需要手动的去修改dom。
vue的数据驱动是通过mvvm这种框架来实现的,mvvm框架主要包含3个部分:model、view、viewmodel。
– model:数据部分;
– view:视图部分;
– viewmodel:连接视图与数据的中间件。
顺着这个思路走下去,我们知道:
– oldindex:元素在数组中的初始索引index;
– elheight:单个元素块的高;
– currtop = clienty - eltop:元素在拖动过程中距离可视区上侧距离;
– currtop - inittop > 0:得知元素是向上拖拽;
– currtop - inittop < 0:得知元素是向下拖拽。
我们以向下拖拽来说:
– 首先,我们要在拖拽结束事件touchend中判断元素从拖动开始到拖动结束时拖动的距离。若小于某个设定的值,则什么也不做;
– 然后,在touchmove事件中判断,若(currtop - inittop) % elheight>= elheight/2成立,即当元素拖至另一个元素块等于或超过1/2的位置时,即可将元素插入到最新的位置为newindex = (currtop - inittop) / elheight + oldindex。
– 最后,若手指离开元素,那么我们在touchend事件中,通过this.draglist.splice(oldindex, 1),this.draglist.splice(newindex, 0, item)重新调整数组顺序。页面会根据最新的draglist渲染列表。
写到这里,我们俨然已经用vue实现了移动端的拖拽功能。但是拖拽体验并不好,接下来,我们对它进行优化。
优化点:我们希望,在元素即将可能落到的位置,提前留出一个可以放得下元素的区域,让用户更好的感知拖拽的灵活性。
方案:(方案已被验证是可行的)将li的结构做一下修改,代码如下:
<ul> <li class="drag-item"><p class="leave-block"></p>// 向上拖拽时留空<p class="">{{item.txt}}</p><p class="leave-block"></p>// 向下拖拽时留空</li></ul>
•拖拽开始:将元素的定位方式由static设置为absolute,z-index设置为一个较大的值,防止元素二次拖拽无效;
•拖拽过程中:将元素即将落入新位置的那个li下p的item.isshow设置为true,其他li下p的item.isshow均设置为false;
•拖拽结束:将所有li下p的item.isshow 均设置为false,将元素定位方式由absolute设置为static。
贴一段伪代码:
touchstart(e){// 获取元素距离视口顶部的初始距离inittop = e.currenttarget.offsettop;// 开始拖动时,获取鼠标距离视口顶部的距离initclienty = e.touches[0].clienty;// 计算出接触点距离元素顶部的距离eltop = e.touches[0].clienty - inittop;},touchmove(index, item, e){// 将拖拽结束时,给元素设置的static定位方式移除,防止元素二次拖拽无效e.target.classlist.remove('static');// 给拖拽的元素设置绝对定位方式e.target.classlist.add('ab');// 获取元素在拖拽过程中距离视口顶部距离currtop = e.touches[0].clienty - eltop;// 元素在拖拽过程中距离视口顶部距离赋给元素e.target.style.top = currtop ;// 获取元素初始位置oldindex = index;// 获取拖拽元素curritem = item;// 若元素已经拖至区域外if(e.touches[0].clienty > (this.draglist.length) * elheight){// 将元素距离上侧的距离设置为拖动区视图的高currtop = (this.draglist.length) * elheight;return;}// 向下拖拽if(currtop > inittop ){// 若拖拽到大于等于元素的一半时,即可将元素插入到最新的位置if((currtop - inittop) % elheight>= elheight / 2){// 计算出元素拖到的最新位置newindex = math.round((currtop - inittop) / elheight) + index;// 确保新元素的索引不能大于等于列表的长度if(newindex < this.draglist.length){// 将所有列表留空处隐藏for(var i = 0;i< this.draglist.length;i++){this.draglist[i].isshow = false;}// 将元素即将拖到的新位置的留空展示this.draglist[newindex].isshow = true;}else {return;}}}// 向上拖拽,原理同上if(currtop < inittop){ ... } }, touchend(e){ // 若拖动距离大于某个设定的值,则按照上述,执行相关代码 if(math.abs(e.changedtouches[0].clienty - initclienty ) > customval){this.draglist.splice(oldindex, 1);this.draglist.splice(newindex, 0, curritem);for(var i = 0;i< this.draglist.length;i++){this.draglist[i].isshow = false;this.draglist[i].isshowup = false;}}e.target.classlist.remove('ab');e.target.classlist.add('static');}
优化后,如下图所示:
以上便是用vue实现移动端拖拽组件的过程。我们知道,有些项目是需要在pc端用vue实现此功能。这里简单提一下pc与移动端的区别如下:
•pc端可以使用的事件组有两种:第一种:h5新特性draggable,dragstart,drag,dragend;第二种:mousedown,mousemove,mouseup;
•pc端获取鼠标坐标是通过e.clientx,clienty,区别于移动端的e.touches[0].clientx,e.touches[0].clienty。
小结
本文从vue拖拽组件开发为例,剖析vue组件的结构、开发思路、vue的数据驱动等,对vue组件化的原理,进行了更深入的理解。 并将vue实现拖拽的方案提供给大家学习研究。
p.s. 牢记一点,切勿在vue中过多得操作dom,要能深入理解vue数据驱动的核心思想。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注!
相关推荐:
vue组件选项props的使用介绍
关于vux uploader 图片上传组件的安装使用方法
vue实现返回顶部backtotop的组件
以上就是关于vue拖拽组件的开发介绍的详细内容。
其它类似信息

推荐信息