vue3 元素拖拽

1. 可拖拽元素及拖拽目标区域

1)可拖拽元素

<div class="drag-el" v-for="item of 8" :key="item" :draggable="true" @dragstart="dragstart($event, item)">{{ item }}</div>

需要注意一点的是:标签直接加draggable,如果元素是文本,需要选中之后才可以进行拖拽;而写成 :draggable="true" 则可以直接进行拖拽,无需选中

2)目标区域

<div class="drop-content" @dragover.prevent @drop="drop"></div>

目前个人理解的最简的写法

拖拽元素开始拖拽 -> 拖拽到目标区域 -> 松开鼠标(拖拽结束)

2. 拖拽过程涉及到的数据传输

开始拖拽时即可拖拽元素的dragstart方法,可以将数据存到event的数据传输对象里

// 开始拖拽
const dragstart = (e: any, data: any) => {
  e.dataTransfer.setData('customData', data)
}

再拖拽结束时可以从event里获取传输的数据

// 鼠标松开事件
const drop = (e: any) => {
  console.log(e.dataTransfer.getData('customData')) // 拖拽传输的数据
  draggableData.value.push(e.dataTransfer.getData('customData'))
}

全部代码如下

<template>
  <div class="drag-page">
    <div class="drag-content">
      <div class="dc-title">可拖拽区域</div>
      <div class="dc-content">
        <div class="dc-el" v-for="item of 8" :key="item" :draggable="true" @dragstart="dragstart($event, item)">{{ item }}</div>
      </div>
    </div>
    <div class="drop-content" @dragover.prevent @drop="drop">
      <div class="dpc-title">可移入区域</div>
      <div class="dpc-content">
        <div class="dpc-el" v-for="(item, index) in draggableData" :key="index" @dblclick="dblClick(index)">{{ item }}</div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const draggableData = ref<any>([])

// 开始拖拽
const dragstart = (e: any, data: any) => {
  e.dataTransfer.setData('customData', data)
}

// 鼠标松开事件
const drop = (e: any) => {
  console.log(e.dataTransfer.getData('customData')) // 拖拽传输的数据
  draggableData.value.push(e.dataTransfer.getData('customData'))
}

// 双击事件
const dblClick = (i: number) => {
  draggableData.value.splice(i, 1)
}
</script>

<style lang="less" scoped>
.drag-page {
  height: 100vh;
  display: flex;
  align-items: center;
  .drag-content {
    width: 250px;
    height: 100%;
    background: #ddd;
    padding: 10px 15px;
    .dc-title {
      text-align: center;
    }
    .dc-content {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      .dc-el {
        margin-top: 20px;
        width: 100px;
        height: 100px;
        background: #ccc;
      }
    }
  }
  .drop-content {
    flex: 1;
    height: 100%;
    background: #fff;
    padding: 10px 15px;
    .dpc-title {
      text-align: center;
    }
    .dpc-content {
      display: flex;
      flex-wrap: wrap;
      .dpc-el {
        margin-top: 20px;
        margin-left: 20px;
        width: 100px;
        height: 100px;
        background: #ccc;
      }
    }
  }
}
</style>

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值