Vue如何实现拖拽穿梭框功能?四种方式分享(附代码)

 3296

Vue项目中如何实现拖拽穿梭框功能?下面本篇文章给大家分享Vue实现拖拽穿梭框功能四种方式,希望对大家有所帮助!


Vue如何实现拖拽穿梭框功能?四种方式分享(附代码)


一、使用原生js实现拖拽

  1. <html>
  2.   <head>
  3.     <meta charset="UTF-8" />
  4.     <title>Lazyload</title>
  5.     <style>
  6.       .drag {
  7.         background-color: skyblue;
  8.         position: absolute;
  9.         line-height: 100px;
  10.         text-align: center;
  11.         width: 100px;
  12.         height: 100px;
  13.       }
  14.     </style>
  15.   </head>
  16.   <body>
  17.     <!-- left和top要写在行内样式里面 -->
  18.     <div style="left: 0; top: 0">按住拖动</div>
  19.     <script src="./jquery-3.6.0.min.js"></script>
  20.     <script>
  21.       // 获取DOM元素
  22.       let dragDiv = document.getElementsByClassName('drag')[0]
  23.       // 鼠标按下事件 处理程序
  24.       let putDown = function (event) {
  25.         dragDiv.style.cursor = 'pointer'
  26.         let offsetX = parseInt(dragDiv.style.left) // 获取当前的x轴距离
  27.         let offsetY = parseInt(dragDiv.style.top) // 获取当前的y轴距离
  28.         let innerX = event.clientX - offsetX // 获取鼠标在方块内的x轴距
  29.         let innerY = event.clientY - offsetY // 获取鼠标在方块内的y轴距
  30.         // 按住鼠标时为div添加一个border
  31.         dragDiv.style.borderStyle = 'solid'
  32.         dragDiv.style.borderColor = 'red'
  33.         dragDiv.style.borderWidth = '3px'
  34.         // 鼠标移动的时候不停的修改div的left和top值
  35.         document.onmousemove = function (event) {
  36.           dragDiv.style.left = event.clientX - innerX + 'px'
  37.           dragDiv.style.top = event.clientY - innerY + 'px'
  38.           // 边界判断
  39.           if (parseInt(dragDiv.style.left) <= 0) {
  40.             dragDiv.style.left = '0px'
  41.           }
  42.           if (parseInt(dragDiv.style.top) <= 0) {
  43.             dragDiv.style.top = '0px'
  44.           }
  45.           if (
  46.             parseInt(dragDiv.style.left) >=
  47.             window.innerWidth - parseInt(dragDiv.style.width)
  48.           ) {
  49.             dragDiv.style.left =
  50.               window.innerWidth - parseInt(dragDiv.style.width) + 'px'
  51.           }
  52.           if (
  53.             parseInt(dragDiv.style.top) >=
  54.             window.innerHeight - parseInt(dragDiv.style.height)
  55.           ) {
  56.             dragDiv.style.top =
  57.               window.innerHeight - parseInt(dragDiv.style.height) + 'px'
  58.           }
  59.         }
  60.         // 鼠标抬起时,清除绑定在文档上的mousemove和mouseup事件
  61.         // 否则鼠标抬起后还可以继续拖拽方块
  62.         document.onmouseup = function () {
  63.           document.onmousemove = null
  64.           document.onmouseup = null
  65.           // 清除border
  66.           dragDiv.style.borderStyle = ''
  67.           dragDiv.style.borderColor = ''
  68.           dragDiv.style.borderWidth = ''
  69.         }
  70.       }
  71.       // 绑定鼠标按下事件
  72.       dragDiv.addEventListener('mousedown', putDown, false)
  73.     </script>
  74.   </body>
  75. </html>


二、VUe使用js实现拖拽穿梭框

  1. <template>
  2.   <div>
  3.     <h3 style="text-align: center">拖拽穿梭框</h3>
  4.     <div id="home" @mousemove="mousemove($event)">
  5.       <div class="tree-select-content">
  6.         <span
  7.           class="select-content"
  8.           :id="'mouse' + index"
  9.           v-for="(item, index) in leftData"
  10.           :key="item.id"
  11.           @mousedown="mousedown(index, 1)"
  12.           @mouseup="mouseup(item, 1, index)"
  13.         >
  14.           <span class="select-text">{{ item.label }}</span>
  15.           <span class="select-text-X" @click="handerClickX(item, index, 1)"
  16.             >X</span
  17.           >
  18.         </span>
  19.       </div>
  20.       <div class="tree-select-content">
  21.         <span
  22.           class="select-content"
  23.           :id="'deleteMouse' + index"
  24.           v-for="(item, index) in rightData"
  25.           :key="item.id"
  26.           @mousedown="mousedown(index, 2)"
  27.           @mouseup="mouseup(item, 2, index)"
  28.         >
  29.           <span class="select-text">{{ item.label }}</span>
  30.           <span class="select-text-X" @click="handerClickX(item, index, 2)"
  31.             >X</span
  32.           >
  33.         </span>
  34.       </div>
  35.     </div>
  36.   </div>
  37. </template>
  38.  
  39. <script>
  40. export default {
  41.   name: "home",
  42.   data() {
  43.     return {
  44.       leftData: [
  45.         { label: "首页", id: 1 },
  46.         { label: "咨询", id: 2 },
  47.         { label: "生活", id: 3 },
  48.         { label: "财富", id: 4 },
  49.         { label: "我的", id: 5 },
  50.       ],
  51.       rightData: [{ label: "世界", id: 6 }],
  52.       isMoveTrue: false,
  53.       isMove: false,
  54.       moveId: "",
  55.     };
  56.   },
  57.   mounted() {},
  58.   components: {},
  59.   methods: {
  60.     mousedown(index, val) {
  61.       this.isMoveTrue = true;
  62.       if (val == 1) {
  63.         this.moveId = "mouse" + index;
  64.       } else {
  65.         this.moveId = "deleteMouse" + index;
  66.       }
  67.     },
  68.     mousemove(event) {
  69.       if (this.isMoveTrue) {
  70.         this.isMove = true;
  71.         document.getElementById(this.moveId).style.position = "absolute";
  72.         document.getElementById(this.moveId).style.top = event.clientY + "px";
  73.         document.getElementById(this.moveId).style.left = event.clientX + "px";
  74.         document.getElementById(this.moveId).style.transform =
  75.           "translate(-50%,-50%)";
  76.       }
  77.     },
  78.     mouseup(item, val, index) {
  79.       if (!this.isMove) {
  80.         this.isMoveTrue = false;
  81.         this.moveId = "";
  82.       }
  83.       if (this.isMoveTrue && val == 2) {
  84.         this.$nextTick(() => {
  85.           this.rightData.splice(index, 1);
  86.           this.leftData.push(item);
  87.         });
  88.       } else if (this.isMoveTrue && val) {
  89.         this.leftData.splice(index, 1);
  90.         this.rightData.push(item);
  91.       }
  92.       document.getElementById(this.moveId).style.display = "none";
  93.       this.isMoveTrue = false;
  94.       this.isMove = false;
  95.       this.moveId = "";
  96.     },
  97.     handerClickX(item, index, val) {
  98.       if (val == 1) {
  99.         this.leftData.splice(index, 1);
  100.         this.rightData.push(item);
  101.       } else {
  102.         this.rightData.splice(index, 1);
  103.         this.leftData.push(item);
  104.       }
  105.     },
  106.   },
  107. };
  108. </script>
  109.  
  110. <style scoped>
  111. #home {
  112.   display: flex;
  113.   justify-content: space-around;
  114. }
  115. .tree-select-content {
  116.   width: 40%;
  117.   height: 300px;
  118.   background: #f9faff;
  119.   border: 1px solid #dee0ec;
  120.   border-radius: 4px;
  121.   display: flex;
  122.   flex-wrap: wrap;
  123.   align-content: baseline;
  124. }
  125. .select-content {
  126.   width: max-content;
  127.   height: 20px;
  128.   padding: 1.6%;
  129.   border: 1px solid #d6dbed;
  130.   margin: 2% 1% 0;
  131.   background: #ffffff;
  132.   box-shadow: 0 0 8px 0 rgba(72, 119, 236, 0.1);
  133.   border-radius: 4px;
  134. }
  135. .select-content:hover span {
  136.   color: #4877ec;
  137. }
  138. .select-content:hover {
  139.   cursor: pointer;
  140.   background: #f8faff;
  141.   border: 1px solid #3e75f4;
  142. }
  143. .select-text {
  144.   font-size: 15px;
  145.   color: #2e2f36;
  146.   text-align: center;
  147.   font-weight: 400;
  148. }
  149. .select-text-{
  150.   font-size: 15px;
  151.   color: #4877ec;
  152.   letter-spacing: 0;
  153.   font-weight: 400;
  154.   margin-left: 12px;
  155.   cursor: pointer;
  156. }
  157. </style>

效果图:

Vue如何实现拖拽穿梭框功能?四种方式分享(附代码)


三、Vue 拖拽组件 vuedraggable

vuedraggable 是标准的组件式封装,并且将可拖动元素放进了 transition-group 上面,过渡动画都比较好。

使用方式:

  1. yarn add vuedraggable
  2.  
  3. import vuedraggable from 'vuedraggable';

在使用的时候,可以通过 v-model 来双向绑定本地 data,如果需要更新或者是触发父组件监听的事件,可以在 updated() 中去 emit。

案例:

  1. <template>
  2.   <div>
  3.     <div>{{ drag ? "拖拽中" : "拖拽停止" }}</div>
  4.     <!--使用draggable组件-->
  5.     <draggable
  6.       v-model="myArray"
  7.       chosenClass="chosen"
  8.       forceFallback="true"
  9.       group="people"
  10.       animation="1000"
  11.       @start="onStart"
  12.       @end="onEnd"
  13.     >
  14.       <transition-group>
  15.         <div class="item" v-for="element in myArray" :key="element.id">
  16.           {{ element.name }}
  17.         </div>
  18.       </transition-group>
  19.     </draggable>
  20.     <div class="color-list">
  21.       <div
  22.         class="color-item"
  23.         v-for="color in colors"
  24.         v-dragging="{ item: color, list: colors, group: 'color' }"
  25.         :key="color.text"
  26.       >
  27.         {{ color.text }}
  28.       </div>
  29.     </div>
  30.   </div>
  31. </template>
  32.   <style scoped>
  33. /*被拖拽对象的样式*/
  34. .item {
  35.   padding: 6px;
  36.   background-color: #fdfdfd;
  37.   border: solid 1px #eee;
  38.   margin-bottom: 10px;
  39.   cursor: move;
  40. }
  41. /*选中样式*/
  42. .chosen {
  43.   border: solid 1px #3089dc !important;
  44. }
  45. </style>
  46.   <script>
  47. //导入draggable组件
  48. import draggable from "vuedraggable";
  49. export default {
  50.   //注册draggable组件
  51.   components: {
  52.     draggable,
  53.   },
  54.   data() {
  55.     return {
  56.       drag: false,
  57.       //定义要被拖拽对象的数组
  58.       myArray: [
  59.         { people: "cn", id: 10, name: "www.itxst.com" },
  60.         { people: "cn", id: 20, name: "www.baidu.com" },
  61.         { people: "cn", id: 30, name: "www.taobao.com" },
  62.         { people: "us", id: 40, name: "www.yahoo.com" },
  63.       ],
  64.       colors: [
  65.         {
  66.           text: "Aquamarine",
  67.         },
  68.         {
  69.           text: "Hotpink",
  70.         },
  71.         {
  72.           text: "Gold",
  73.         },
  74.         {
  75.           text: "Crimson",
  76.         },
  77.         {
  78.           text: "Blueviolet",
  79.         },
  80.         {
  81.           text: "Lightblue",
  82.         },
  83.         {
  84.           text: "Cornflowerblue",
  85.         },
  86.         {
  87.           text: "Skyblue",
  88.         },
  89.         {
  90.           text: "Burlywood",
  91.         },
  92.       ],
  93.     };
  94.   },
  95.   methods: {
  96.     //开始拖拽事件
  97.     onStart() {
  98.       this.drag = true;
  99.     },
  100.     //拖拽结束事件
  101.     onEnd() {
  102.       this.drag = false;
  103.     },
  104.   },
  105. };
  106. </script>


四、Awe-dnd指令封装

vue-dragging 的 npm 包的名字是 awe-dnd ,并不是 vue-dragging,这个库的特点是封装了 v-dragging 全局指令,然后通过全局指令去数据绑定等。

相比及 vuedraggable 来说, awe-dnd 是没有双向绑定(这里没有双向绑定并不是很严谨,准确的来说没有暴露双向绑定的方式),因此提供了事件,在拖拽结束的时候用来更新列表(不需要手动更新列表,其实内部是实现了双向绑定的)或者是去触发父组件监听的事件。

安装依赖:

  1. npm install awe-dnd --save
  2. yarn add awe-and

main.js

  1. import VueDND from 'awe-dnd'
  2.  
  3. Vue.use(VueDND)

案例:

  1. <template>
  2.   <div>
  3.     <div class="color-list">
  4.       <div
  5.         class="color-item"
  6.         v-for="color in colors"
  7.         v-dragging="{ item: color, list: colors, group: 'color' }"
  8.         :key="color.text"
  9.       >
  10.         {{ color.text }}
  11.       </div>
  12.     </div>
  13.   </div>
  14. </template>
  15. <style scoped>
  16. /*被拖拽对象的样式*/
  17. .item {
  18.   padding: 6px;
  19.   background-color: #fdfdfd;
  20.   border: solid 1px #eee;
  21.   margin-bottom: 10px;
  22.   cursor: move;
  23. }
  24. /*选中样式*/
  25. .chosen {
  26.   border: solid 1px #3089dc !important;
  27. }
  28. </style>
  29. <script>
  30. export default {
  31.   data() {
  32.     return {
  33.       drag: false,
  34.       colors: [
  35.         {
  36.           text: "Aquamarine",
  37.         },
  38.         {
  39.           text: "Hotpink",
  40.         },
  41.         {
  42.           text: "Gold",
  43.         },
  44.         {
  45.           text: "Crimson",
  46.         },
  47.         {
  48.           text: "Blueviolet",
  49.         },
  50.         {
  51.           text: "Lightblue",
  52.         },
  53.         {
  54.           text: "Cornflowerblue",
  55.         },
  56.         {
  57.           text: "Skyblue",
  58.         },
  59.         {
  60.           text: "Burlywood",
  61.         },
  62.       ],
  63.     };
  64.   },
  65.   methods: {},
  66. };
  67. </script>


TAG标签:
本文网址:https://www.zztuku.com/index.php/detail-13158.html
站长图库 - Vue如何实现拖拽穿梭框功能?四种方式分享(附代码)
申明:本文转载于《博客园》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    MAC环境配置定时任务