Vue拖拽组件

vue

vue开发公众号项目,***产品需要添加一个新的功能。拖拽功能。一听简单。百度上轮子挺多,直接拉一个过来用着就行。然鹅。。。兴奋之余,却失望至极。东西很多,没有一个能使得。你让我失望,那我就让你绝望。于是,拖拽的故事就开始了。。

vue拖拽功能组件源码

vue拖拽功能

必备知识点:

先给不懂的童鞋补充下流程,文章要细读方能拖动元素到你心里~

按下的时候,我们需要获取

元素当前的 具有相对定位元素的左侧距离

元素当前的具有相对定位元素的顶部距离

鼠标按下点的x轴距离(鼠标左侧的距离)

鼠标按下点的y轴距离 (鼠标顶部的距离)

获取到这些点,先存储起来,后面的计算需要用到这些值

  start(e){

// 如果touches存在就说明是移动端

// 否则为pc端直接获取事件源对象

let touch = e.touches? e.touches[0] : e;

this.position.x = touch.clientX;

this.position.y = touch.clientY;

this.dx = moveDiv.offsetLeft;

this.dy = moveDiv.offsetTop;

}

Step1.

让元素跟着鼠标的移动不断移动。既然鼠标的x轴和y轴可以获取到,那我们就可以通过计算来让元素实现移动。

移动的时候,我们需要获取并设置

鼠标此时的当前的x轴和y轴的距离

鼠标点击的x轴和y轴的距离(按下的时候定义过)

此时用移动的距离 - 点击的起始位置就是移动的距离。

赋值给点击元素的left和top即可。

补充:计算的方式很多种,这知识其中一种

  move(e){

let touch = e.touches? e.touches[0] : e;

this.nx = touch.clientX - this.position.x;

this.ny = touch.clientY - this.position.y;

this.xPum = this.dx+this.nx;

this.yPum = this.dy+this.ny;

moveDiv.style.left = this.xPum + "px";

moveDiv.style.top = this.yPum + "px";

},

Step2.

离开的时候,我们需要抬起和移动事件从栈中清除掉,并且在结束时对边界做一个处理。不让元素拖动到屏幕外面,否则的话,不小心拖出去了,拉都拉不回来。这就很尴尬了。

元素的宽度

父元素的宽度和高度

元素的左侧距离 + 元素的宽度

元素的顶部距离 + 元素的高度

end(e){

let oWidth = moveDiv.offsetWidth; // Element Width

let oWrapWidth = moveDiv.parentNode.offsetWidth; // Parent Element Width

let oWrprapHeight = moveDiv.parentNode.offsetHeight; // Parent Element Height

let sumWidth = moveDiv.offsetLeft + oWidth; // Element Left + Element Width

let sumHeight = moveDiv.offsetTop + moveDiv.offsetHeight; // Element Top + Element Height

// The Limit Deal

if(moveDiv.offsetLeft < 0) {

moveDiv.style.left = 0;

} else if(sumWidth > oWrapWidth){

moveDiv.style.left = oWrapWidth - oWidth + 'px';

} else if(moveDiv.offsetTop < 0) {

moveDiv.style.top = 0;

} else if(sumHeight > oWrprapHeight) {

moveDiv.style.top = oWrprapHeight - moveDiv.offsetHeight + 'px';

}

document.onmousemove = null;

document.onmouseup = null;

}

组件源码

考虑到复用性,pc和移动端。

<template>

<!--S 拖动组件 -->

<div class="drag" >

@mousedown="start($event)" @touchstart="start($event)"

@mousemove="move($event)" @touchmove="move($event)"

@mouseup="end($event)" @touchend="end($event)">

<slot name="drag-cont"></slot>

</div><!--E 拖动组件 -->

</template>

<script>

export default {

data() {

return {

position: {x: 0,y: 0}, // 鼠标点击的x轴和y轴的距离

nx: '', // 鼠标当前距离元素的左侧距离

ny: '', // 鼠标当前距离元素的顶部距离

dx: '', // 元素距离左侧的距离

dy: '', // 元素距离顶部的距离

xPum: '', // 元素移动的x轴距离

yPum: '', // 元素移动的y轴距离

}

},

methods: {

start(e){

// 如果touches存在就说明是移动端

// 否则为pc端直接获取事件源对象

let touch = e.touches? e.touches[0] : e;

this.position.x = touch.clientX;

this.position.y = touch.clientY;

this.dx = moveDiv.offsetLeft;

this.dy = moveDiv.offsetTop;

},

move(e){

let touch = e.touches? e.touches[0] : e;

this.nx = touch.clientX - this.position.x;

this.ny = touch.clientY - this.position.y;

this.xPum = this.dx+this.nx;

this.yPum = this.dy+this.ny;

moveDiv.style.left = this.xPum + "px";

moveDiv.style.top = this.yPum + "px";

document.addEventListener("touchmove",function(){

event.preventDefault();

},false);

if(e.preventDefault){

e.preventDefault();

}else{

window.event.returnValue == false;

}

},

end(e){

let oWidth = moveDiv.offsetWidth; // Element Width

let oWrapWidth = moveDiv.parentNode.offsetWidth; // Parent Element Width

let oWrprapHeight = moveDiv.parentNode.offsetHeight; // Parent Element Height

let sumWidth = moveDiv.offsetLeft + oWidth; // Element Left + Element Width

let sumHeight = moveDiv.offsetTop + moveDiv.offsetHeight; // Element Top + Element Height

// The Limit Deal

if(moveDiv.offsetLeft < 0) {

moveDiv.style.left = 0;

} else if(sumWidth > oWrapWidth){

moveDiv.style.left = oWrapWidth - oWidth + 'px';

} else if(moveDiv.offsetTop < 0) {

moveDiv.style.top = 0;

} else if(sumHeight > oWrprapHeight) {

moveDiv.style.top = oWrprapHeight - moveDiv.offsetHeight + 'px';

}

document.onmousemove = null;

document.onmouseup = null;

}

}

}

</script>

<style lang="less" scoped>

.drag {

position: absolute;

left: 0;

right: 0;

z-index: 999;

}

</style>

引入Demo

    

 <Drag class="drag">

<div slot="drag-cont">订单记录</div>

</Drag>

<style>

.drag {

width: .6rem;

height: .6rem;

background-color: rgba(0, 0, 0,.55);

text-align: center;

line-height: .6rem;

font-size: .14rem;

color: #ffffff;

}

</style>

使用的时候,给组件添加类名,添加样式即可。

以上是 Vue拖拽组件 的全部内容, 来源链接: utcz.com/z/378504.html

回到顶部