vue和H5 draggable实现拖拽并替换效果


Posted in Javascript onJuly 29, 2020

前言

公司项目需要做拖拽替换效果,本人用的vue框架。在网上找了很多资料都是用的 Vue.Draggable(git地址)。但这个组件实现的拖拽后插入效果,我倒腾了很久也没有替换效果(如果Vue.Draggable能实现拖拽替换效果的话请大神给我留言)。

JQ有实现拖拽的插件,我下载过一个插件并看过源码,大致原理是给目标元素设置定位属性,通过监听鼠标mousedown,mouseup事件,再计算鼠标位置变化,然后给元素样式设置偏移值来实现拖拽效果的。

H5提供了专门的拖拽API 给元素添加 draggable 属性,设置为 true就能实现拖拽了。本文使用的H5提供的拖拽API 以及vue 无其他任何添加,请放心使用

直接上代码

<template>
 <div class="container">
  <div class="layout">
   <button
    class="layout-btn"
    @click="layoutType=val.value"
    v-for="val in layoutOptions"
    :key="val.value"
   >{{val.label}}</button>
  </div>

  <div
   class="group"
   :class="{'left-top-container': gindex===0,
    'right-top-container': gindex===1,
    'bottom-container': gindex===2,
    'top-container': gindex<2}"
   v-for="(group,gindex) in data"
   :key="gindex"
  >
   <div
    class="cls-default"
    v-for="(item,cindex) in group.children"
    :key="cindex"
    :data-id="gindex+'-'+cindex"
    draggable="true"
    @dragstart="onDragstart($event)"
    @dragend="onDragend($event)"
    @dragover="onDragover($event)"
    @drop="onDrop($event)"
    :style="{'background-color': item.color}"
    :class="{'cls1-0': cindex ===0 && layoutType==1,
    'cls2-0': (cindex ===0 || cindex ===1) && layoutType==2,
    'cls3-0': cindex ===0 && layoutType==3,
    'cls3-1': (cindex ===1 || cindex ===2) && layoutType==3,
    'cls4-0': cindex <4 && layoutType==4,
    'cls6-0': cindex === 0 && layoutType==6
    }"
   >
    <div class="content">{{item.color ? item.color : '我是空对象'}}</div>
   </div>
  </div>
  <div class="tips">上面两个区域内是展示区的内容能互相拖拽
   <br>下面的是资源区,只能复制出去覆盖目标区域,本身不会被替换掉
  </div>
 </div>
</template>

<script>
export default {
 data() {
  return {
   stargindex: "",
   endIndex: "",
   layoutType: "9",
   layoutOptions: [
    { label: "单分屏", value: 1 },
    { label: "二分屏", value: 2 },
    { label: "三分屏", value: 3 },
    { label: "四分屏", value: 4 },
    { label: "六分屏", value: 6 },
    { label: "九分屏", value: 9 }
   ],
   data: [
    {
     group: "left-show",
     title: "视频播放区一",
     children: [
      {
       id: 6,
       color: "orange"
      },
      {
       id: 2,
       color: "yellow"
      },
      {},
      {},
      {},
      {},
      {
       id: 3,
       color: "cyan"
      },
      {},
      {
       id: 5,
       color: "brown"
      }
     ]
    },
    {
     group: "right-show",
     title: "视频播放区二",
     children: [
      {},
      {
       id: 7,
       color: "pink"
      },
      {},
      {},
      { id: 4, color: "purple" },
      {},
      {},
      {},
      {
       id: 10,
       color: "gray"
      }
     ]
    },
    {
     group: "source",
     title: "视频资源区",
     children: [
      {
       id: 11,
       color: "white"
      },
      {
       id: 12,
       color: "black"
      },
      {
       id: 13,
       color: "red"
      },
      {
       id: 14,
       color: "green"
      },
      {
       id: 15,
       color: "blue"
      }
     ]
    }
   ]
  };
 },
 methods: {
  onDragstart(event) {
   this.stargindex = event.target.getAttribute("data-id");
  },
  onDragend(event) {
   let startGroupIndex = this.stargindex.split("-")[0];
   let startChildIndex = this.stargindex.split("-")[1];
   let endGroupIndex = this.endIndex.split("-")[0];
   let endChildIndex = this.endIndex.split("-")[1];
   // 对数据做简单的深拷贝 目前不需要
   // let endObj = JSON.parse(
   //  JSON.stringify(this.data[endGroupIndex].children[endChildIndex])
   // );
   // let startObj = JSON.parse(
   //  JSON.stringify(this.data[startGroupIndex].children[startChildIndex])
   // );
   let endObj = this.data[endGroupIndex].children[endChildIndex];
   let startObj = this.data[startGroupIndex].children[startChildIndex];
   if (this.data[endGroupIndex].group === "source") {
    //往资源区拖拽时 不做任何替换操作
    return;
   }
   this.data[endGroupIndex].children.splice(endChildIndex, 1, startObj);
   if (this.data[startGroupIndex].group !== "source") {
    //拖拽起始区域不是 source时 把起始区域替换成拖拽后区域的数据
    this.data[startGroupIndex].children.splice(startChildIndex, 1, endObj);
   }
  },
  onDrop(event) {
   if (event.target.className.indexOf("cls-default") > -1) {
    this.endIndex = event.target.getAttribute("data-id");
   } else {
    this.endIndex = event.target.parentElement.getAttribute("data-id");
   }
  },
  onDragover(event) {
   event.preventDefault();
  }
 }
};
</script>

<style scoped>
.container {
 background-color: #eee;
 height: 800px;
}
.layout .layout-btn {
 background-color: #409eff;
 color: #fff;
 padding: 10px 15px;
 margin: 10px 15px;
}
.tips {
 font-size: 24px;
 text-align: center;
}
.group {
 float: left;
 overflow: hidden;
 box-sizing: border-box;
}
.group-title {
 height: 40px;
 line-height: 40px;
}
.cls-default {
 float: left;
 margin: 0;
 box-sizing: border-box;
 overflow: hidden;
 border: 1px solid #999;
}
.cls-default .content {
 text-align: center;
 padding-top: 20px;
 font-size: 20px;
}
.top-container {
 height: 400px;
 width: 40%;
 margin: 15px 5%;
}
.top-container .cls-default {
 width: 33.33%;
 height: 33.33%;
}
.top-container .cls1-0 {
 width: 100%;
 height: 100%;
}
.top-container .cls2-0 {
 width: 50%;
 height: 100%;
}
.top-container .cls3-0 {
 width: 50%;
 height: 100%;
}
.top-container .cls3-1 {
 width: 50%;
 height: 50%;
}
.top-container .cls4-0 {
 width: 50%;
 height: 50%;
}
.top-container .cls6-0 {
 width: 66.66%;
 height: 66.65%;
}
.bottom-container {
 width: 90%;
 height: 200px;
 margin: 15px 5%;
}
.bottom-container .cls-default {
 width: 15%;
 height: 150px;
}
</style>

写在最后

本文是我第一次写博客,写的比较随意,样式处理也是很随心。如有错误请指正。

后面有时间会完善组件的功能。参考Vue.Draggable(git地址)这个组件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
解读JavaScript中 For, While与递归的用法
May 07 Javascript
Jquery中children与find之间的区别详细解析
Nov 29 Javascript
jQuery中position()方法用法实例
Jan 16 Javascript
使用mouse事件实现简单的鼠标经过特效
Jan 30 Javascript
JS控制静态页面之间传递参数获取参数并应用的简单实例
Aug 10 Javascript
关于js函数解释(包括内嵌,对象等)
Nov 20 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
Jan 09 Javascript
ajax请求data遇到的问题分析
Jan 18 Javascript
vue-cli启动本地服务局域网不能访问的原因分析
Jan 22 Javascript
layui弹出层按钮提交iframe表单的方法
Aug 20 Javascript
如何通过shell脚本自动生成vue文件详解
Sep 10 Javascript
Node实现搜索框进行模糊查询
Jun 28 Javascript
vue同个按钮控制展开和折叠同个事件操作
Jul 29 #Javascript
JavaScript编写开发动态时钟
Jul 29 #Javascript
js编写简易的计算器
Jul 29 #Javascript
从0到1学习JavaScript编写贪吃蛇游戏
Jul 28 #Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
Jul 28 #Javascript
Node.js 深度调试方法解析
Jul 28 #Javascript
vue-列表下详情的展开与折叠案例
Jul 28 #Javascript
You might like
PHP通用检测函数集合
2011/02/08 PHP
php中读写文件与读写数据库的效率比较分享
2013/10/19 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
2014/07/01 PHP
php数组索引与键值操作技巧实例分析
2015/06/24 PHP
Yii2隐藏frontend/web和backend/web的方法
2015/12/12 PHP
可以把编码转换成 gb2312编码lib.UTF8toGB2312.js
2007/08/21 Javascript
IE与Firefox下javascript getyear年份的兼容性写法
2007/12/20 Javascript
js实现点击链接后窗口缩小并居中的方法
2015/03/02 Javascript
JavaScript中数组继承的简单示例
2015/07/29 Javascript
Vuejs第六篇之Vuejs与form元素实例解析
2016/09/05 Javascript
JavaScript-html标题滚动效果的简单实现
2016/09/08 Javascript
smartupload实现文件上传时获取表单数据(推荐)
2016/12/12 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题
2019/11/06 Javascript
javascript实现拖拽碰撞检测
2020/03/12 Javascript
Js on及addEventListener原理用法区别解析
2020/07/11 Javascript
python控制台英汉汉英电子词典
2020/04/23 Python
python 3.6 tkinter+urllib+json实现火车车次信息查询功能
2017/12/20 Python
PyQt5打开文件对话框QFileDialog实例代码
2018/02/07 Python
Python 确定多项式拟合/回归的阶数实例
2018/12/29 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
2019/01/14 Python
使用python实现CGI环境搭建过程解析
2020/04/28 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
使用spring mvc+localResizeIMG实现HTML5端图片压缩上传的功能
2016/12/16 HTML / CSS
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
加拿大领先的牛仔零售商:Bluenotes
2018/01/22 全球购物
土木工程毕业生推荐信
2013/10/28 职场文书
大学生村官典型材料
2014/01/12 职场文书
客户经理岗位职责
2015/01/31 职场文书
元旦联欢晚会主持词
2015/07/01 职场文书
选对餐饮营销策略,营业额才会上涨
2019/08/27 职场文书
SpringCloud Alibaba项目实战之nacos-server服务搭建过程
2021/06/21 Java/Android
Java实现二分搜索树的示例代码
2022/03/17 Java/Android