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面象对象设计
Apr 28 Javascript
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
Mar 14 Javascript
JQuery-tableDnD 拖拽的基本使用介绍
Jul 04 Javascript
获取鼠标在div中的相对位置的实现代码
Dec 30 Javascript
JavaScript初学者建议:不要去管浏览器兼容
Feb 04 Javascript
this,this,再次讨论javascript中的this,超全面(经典)
Jan 05 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
Javascript继承机制详解
May 30 Javascript
JS判断时间段的实现代码
Jun 14 Javascript
node+koa实现数据mock接口的方法
Sep 20 Javascript
微信小程序防止多次点击跳转(函数节流)
Sep 19 Javascript
JS轻量级函数式编程实现XDM三
Jun 16 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 split汉字
2009/06/05 PHP
Yii安装与使用Excel扩展的方法
2016/07/13 PHP
PHP查询大量数据内存耗尽问题的解决方法
2016/10/28 PHP
用Greasemonkey 脚本收藏网站会员信息到本地
2009/10/26 Javascript
JS分页控件 可用于无刷新分页
2013/07/23 Javascript
jquery mobile事件多次绑定示例代码
2013/09/13 Javascript
JS判断两个时间大小的示例代码
2014/01/28 Javascript
JavaScript的new date等日期函数在safari中遇到的坑
2016/10/24 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
Vue.2.0.5过渡效果使用技巧
2017/03/16 Javascript
jQuery插件FusionCharts绘制的2D帕累托图效果示例【附demo源码】
2017/03/28 jQuery
Angular使用Md5加密的解决方法
2017/09/16 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
2017/12/06 Javascript
Vuex 进阶之模块化组织详解
2018/01/12 Javascript
JS实现的3des+base64加密解密算法完整示例
2018/05/18 Javascript
layer.confirm取消按钮绑定事件的方法
2018/08/17 Javascript
node全局变量__dirname与__filename的区别
2019/01/14 Javascript
详解Vue.directive 自定义指令
2019/03/27 Javascript
使用Node.js在深度学习中做图片预处理的方法
2019/09/18 Javascript
Vue 实现CLI 3.0 + momentjs + lodash打包时优化
2019/11/13 Javascript
Python中itertools模块用法详解
2014/09/25 Python
Python实现的选择排序算法示例
2017/11/29 Python
Python实现的多进程和多线程功能示例
2018/05/29 Python
解决pycharm运行时interpreter为空的问题
2018/10/29 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
python利用datetime模块计算程序运行时间问题
2020/02/20 Python
django model通过字典更新数据实例
2020/04/01 Python
使用Keras构造简单的CNN网络实例
2020/06/29 Python
HTML5验证以及日期显示的实现详解
2013/07/05 HTML / CSS
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
分公司负责人任命书
2014/06/04 职场文书
校园绿化美化方案
2014/06/08 职场文书
学校教研活动总结
2014/07/02 职场文书
中韩经贸翻译专业大学生职业生涯规划范文
2014/09/18 职场文书
2014年健康教育工作总结
2014/11/20 职场文书
关于教师节的广播稿
2015/08/19 职场文书