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‘)"  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‘)"  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>

  

原文地址:https://www.cnblogs.com/yayaonly/p/12114270.html

时间: 2024-10-08 18:24:55

vue实现拖拽组件的相关文章

弹窗拖拽组件开发应用

需要注意的问题包括: 1.this的指向到底是指向谁--弄清楚所指的对象 2.深入理解原型的概念及使用: 去改写对象下面公用的方法或者属性 , 让公用的方法或者属性在内存中存在一份 ( 提高性能) 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5 <

自定义事件拖拽组件

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>自定义事件拖拽组件</title> <style> #div1{ width:100px; height:100px; background:red; position:abs

如何使用Vue实现拖拽效果pageY、screenY、clientY、layerY、offsetY(转)

如何使用Vue实现拖拽效果pageY.screenY.clientY.layerY.offsetY 2018年06月28日 17:34:42 唐策 阅读数:377 标签: 如何使用Vue实现拖拽效果pageY.screenY.cli 更多 个人分类: vue-js 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_29132907/article/details/80846652 1.效果图 2.分清clientY pageY screenY

vue2-dragula vue拖拽组件

Drag and drop so simple it hurts Vue wrapper for dragula drag'n drop library, based on vue-dragula by @Astray-git. vue 为 dragula 拖拽 包装 减少 代码,基于   vue-dragula. This library has been refactored, upgraded and extended with powerful new features for use

Vue 组件总结 (一、拖拽组件 Vue-draggable)

一.vue-draggable 安装使用npm地址: https://www.npmjs.com/package/vuedraggable 二.表格拖拽使用, 举例: <table class="table table-condensed"> <thead> <tr> <th>视频ID</th> <th>名称</th> <th>作者</th> <th>创建时间<

Vue+element 需要用到拖拽组件 vuedraggable

新需求是要求界面上的14个可以拖拽,点击保存之后保存拖拽之后的顺序. 确定需求之后肯定第一时间是百度,发现有个插件vuedragger拖拽,按照教程就懵懂的开始了. 官方示例:https://david-desmaisons.github.io/draggable-example/ 1.安装 npm install vuedraggable 2.引入 import draggable from 'vuedraggable' 3.注册 components: { draggable } html

vue卡片拖拽、自动排列交换位置、拖拽数据存取

这是这次系列文章的第一篇,我自己封装了一个用vue实现的拖动卡片组件,并且发布到npm,详细地记录下来了整体制作过程.总共有三篇文章,介绍组件的制作思路和遇到的问题,以及在发布到npm上并下载使用的过程中,发生了什么问题并如何解决. 第一篇为组件封装后的使用文档及介绍 第二篇为组件的实现思路以及遇到的问题 第三篇为将组件打包并上传至npm,如何实现按需加载和下载后使用的问题 这是vue实现的拖动卡片组件,主要实现了: 拖动卡片与其他卡片的位置更换,并且其他卡片根据拖动的位置自动顺移,位置数据实时

vue模块拖拽效果

正巧在之前面试中遇到问实现拖拽效果 当时面试的时候简单回答了实现的方式与逻辑. 现在闲来无事,把这个东西实现了一下. 原理很简单,写的很方便. 数据驱动,建立一个数组,数组初始长度为1 拖动触发时,添加一个对象到数组中,拖动的是下标为0的对象,新建的还在原来位置放着,等待下次拖动. 话不多说,上代码 <template> <div class="view"> <div class="x" @mousedown="move($e

拖拽组件3--转秒味课堂课件

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <style> #div1{ width:100px; height:100px; background:red; position:absolut