vue实现拖拽组件

可以拖拽,靠边停靠,效果图如下
代码如下:
注意:代码中使用的图片未上传
DragAndDrop组件:
<template>
    <div class="drag" id="moveDiv"
         @mousedown="start($event)" @touchstart="start($event)"
         @mousemove="move($event)" @touchmove="move($event)"
         @mouseup="end($event)" @touchend="end($event)">
        <slot name="drag-cont"></slot>
        <div id="optionBall"></div>
        <div id="optionContent" v-show="optionContentShow">
            <span class="imgWrap" @click="gatewayOption" v-bind:style="{backgroundColor : this.$parent.whichOption? '#ff5b45' : '#ffffff'}" >
                <img v-bind:src="this.$parent.whichOption?require('../assets/img/SmartGateway_write.png'):require('../assets/img/SmartGateway.png')" alt="" width="24px" height="24px">
            </span>
            <span class="imgWrap" @click="alertOption" v-bind:style="{backgroundColor : !this.$parent.whichOption? '#ff5b45' : '#ffffff'}">
                <img v-bind:src="!this.$parent.whichOption?require('../assets/img/alert_write.png'):require('../assets/img/alert.png')" alt="" width="24px" height="24px">
            </span>
        </div>
    </div><!--E 拖动组件 -->
</template>

<script>
    export default {
        name: "dragAndDrop",
        data() {
            return {
                position: {x: 0,y: 0}, // 鼠标点击的x轴和y轴的距离
                nx: '',    // 鼠标当前距离元素的左侧距离
                ny: '',    // 鼠标当前距离元素的顶部距离
                dx: '',    // 元素距离左侧的距离
                dy: '',    // 元素距离顶部的距离
                xPum: '',  // 元素移动的x轴距离
                yPum: '',   // 元素移动的y轴距离
                optionContentShow: true
            };
        },
        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;
                this.optionContentShow = true;
            },
            move(e){
                this.isDrop = true;
                if(this.isDrop){
                    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;
                    this.optionContentShow = false;
                    moveDiv.style.left = "-30px";
                } else if(sumWidth > oWrapWidth){
                    moveDiv.style.left = oWrapWidth - oWidth + 'px';
                    // console.log("到最右边了");
                    this.optionContentShow = false;
                    moveDiv.style.left = "-30px";
                } 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;
            },
            gatewayOption: function () {
                this.$parent.gatewayOption();
            },
            alertOption: function () {
                this.$parent.alertOption();
            },
        }
    };
</script>

<style scoped>
    .drag {
        width: 160px;
        height: 60px;
        position: absolute;
        left: 40px;
        bottom: 60px;
        z-index: 999;
    }

    #optionBall {
        width: 56px;
        height: 56px;
        position: absolute;
        background-color: #ff5b45;
        border-radius: 56px;
        z-index: 20;
    }

    #optionContent {
        width: 130px;
        height: 50px;
        background-color: #ff956b;
        position: absolute;
        left: 20px;
        margin-top: 3px;
        border-radius: 50px;
        z-index: 10;
        padding: 6px 0 6px 34px;
        box-sizing: border-box;
    }

    .imgWrap {
        display: inline-block;
        width: 38px;
        height: 38px;
        background-color: #ffffff;
        border-radius: 40px;
        padding: 8px;
        box-sizing: border-box;
    }

    .checked {
        background-color: #ff5b45;
    }
</style>

父组件:subDevice.vue
<template>
  <DragAndDrop></DragAndDrop>
</template>
<script>
    import DragAndDrop from "./DragAndDrop";
   export default {
     name: "subDevice",
     components: {DragAndDrop,InfiniteScroll},
        data() {
            return {
          whichOption: true
            }
        },
    methods:{
      gatewayOption: function () {
        this.whichOption = true;
      },
      alertOption: function () {
          this.whichOption = false;
      }
    }
  }
</script>
 

  

猜你喜欢

转载自www.cnblogs.com/yayaonly/p/12114270.html