Vue实现拖拽穿梭框功能四种方式

118 篇文章 2 订阅

一、使用原生js实现拖拽

123

<head>
  <meta charset="UTF-8" />
  <title>Lazyload</title>
  <style>
    .drag {
      background-color: skyblue;
      position: absolute;
      line-height: 100px;
      text-align: center;
      width: 100px;
      height: 100px;
    }
  </style>
</head>
<body>
  <!-- left和top要写在行内样式里面 -->
  <div class="drag" style="left: 0; top: 0">按住拖动</div>
  <script src="./jquery-3.6.0.min.js"></script>
  <script>
    // 获取DOM元素
    let dragDiv = document.getElementsByClassName('drag')[0]
    // 鼠标按下事件 处理程序
    let putDown = function (event) {
      dragDiv.style.cursor = 'pointer'
      let offsetX = parseInt(dragDiv.style.left) // 获取当前的x轴距离
      let offsetY = parseInt(dragDiv.style.top) // 获取当前的y轴距离
      let innerX = event.clientX - offsetX // 获取鼠标在方块内的x轴距
      let innerY = event.clientY - offsetY // 获取鼠标在方块内的y轴距
      // 按住鼠标时为div添加一个border
      dragDiv.style.borderStyle = 'solid'
      dragDiv.style.borderColor = 'red'
      dragDiv.style.borderWidth = '3px'
      // 鼠标移动的时候不停的修改div的left和top值
      document.onmousemove = function (event) {
        dragDiv.style.left = event.clientX - innerX + 'px'
        dragDiv.style.top = event.clientY - innerY + 'px'
        // 边界判断
        if (parseInt(dragDiv.style.left) <= 0) {
          dragDiv.style.left = '0px'
        }
        if (parseInt(dragDiv.style.top) <= 0) {
          dragDiv.style.top = '0px'
        }
        if (
          parseInt(dragDiv.style.left) >=
          window.innerWidth - parseInt(dragDiv.style.width)
        ) {
          dragDiv.style.left =
            window.innerWidth - parseInt(dragDiv.style.width) + 'px'
        }
        if (
          parseInt(dragDiv.style.top) >=
          window.innerHeight - parseInt(dragDiv.style.height)
        ) {
          dragDiv.style.top =
            window.innerHeight - parseInt(dragDiv.style.height) + 'px'
        }
      }
      // 鼠标抬起时,清除绑定在文档上的mousemove和mouseup事件
      // 否则鼠标抬起后还可以继续拖拽方块
      document.onmouseup = function () {
        document.onmousemove = null
        document.onmouseup = null
        // 清除border
        dragDiv.style.borderStyle = ''
        dragDiv.style.borderColor = ''
        dragDiv.style.borderWidth = ''
      }
    }
    // 绑定鼠标按下事件
    dragDiv.addEventListener('mousedown', putDown, false)
  </script>
</body>

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

<h3 style="text-align: center">拖拽穿梭框</h3>
<div id="home" @mousemove="mousemove($event)">
  <div class="tree-select-content">
    <span
      class="select-content"
      :id="'mouse' + index"
      v-for="(item, index) in leftData"
      :key="item.id"
      @mousedown="mousedown(index, 1)"
      @mouseup="mouseup(item, 1, index)"
    >
      <span class="select-text">{{ item.label }}</span>
      <span class="select-text-X" @click="handerClickX(item, index, 1)"
        >X</span
      >
    </span>
  </div>
  <div class="tree-select-content">
    <span
      class="select-content"
      :id="'deleteMouse' + index"
      v-for="(item, index) in rightData"
      :key="item.id"
      @mousedown="mousedown(index, 2)"
      @mouseup="mouseup(item, 2, index)"
    >
      <span class="select-text">{{ item.label }}</span>
      <span class="select-text-X" @click="handerClickX(item, index, 2)"
        >X</span
      >
    </span>
  </div>
</div>

效果图:
在这里插入图片描述

三、Vue 拖拽组件 vuedraggable

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

使用方式:

yarn add vuedraggable

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

案例:

<div>{{ drag ? "拖拽中" : "拖拽停止" }}</div>
<!--使用draggable组件-->
<draggable
  v-model="myArray"
  chosenClass="chosen"
  forceFallback="true"
  group="people"
  animation="1000"
  @start="onStart"
  @end="onEnd"
>
  <transition-group>
    <div class="item" v-for="element in myArray" :key="element.id">
      {{ element.name }}
    </div>
  </transition-group>
</draggable>
<div class="color-list">
  <div
    class="color-item"
    v-for="color in colors"
    v-dragging="{ item: color, list: colors, group: 'color' }"
    :key="color.text"
  >
    {{ color.text }}
  </div>
</div>
# 四、Awe-dnd指令封装 vue-dragging 的 npm 包的名字是 awe-dnd ,并不是 vue-dragging,这个库的特点是封装了 v-dragging 全局指令,然后通过全局指令去数据绑定等。

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

安装依赖:

npm install awe-dnd --save
yarn add awe-and
main.js

import VueDND from ‘awe-dnd’

Vue.use(VueDND)
案例:

{{ color.text }}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值