vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽

文章目录

    • 功能一:使用H5 拖放事件实现一个拖拉拽
      • ✏️ 拖放逻辑以及流程
        • 1. 基本布局-- 使用for遍历出列表并添加draggable 属性设置为 true,把元素设置为可拖放
        • 2. 添加拖动开始事件dragstart,拖动结束事件dragenter
        • 3. 2中视觉上拖拽不明显,添加拖动时候原始数据隐藏(opacity: 0;),拖宅结束后释放隐藏元素到最新位置
      • ✏️ 九宫格拖拽
        • 展示效果
      • ✏️ 完整代码


注释: 接上期[管理系统之增删改查],(https://blog.csdn.net/men_gqi/article/details/131718259?spm=1001.2014.3001.5501)这篇实战一些插件和api

屏幕录制2023-07-21 14.57.01

功能一:使用H5 拖放事件实现一个拖拉拽

知识备注:
拖动事件:dragstart、drag、dragend
放置事件:dragenter、dragover、drop

✏️ 拖放逻辑以及流程

从拖动元素放置到目标元素上依次触发
dragstart(触发拖动事件)—> dragenter(拖拉进入当前节点时触发当前节点) --------->dragover(增加视觉感这个博主总结的挺详细的) ----> dragend(当拖动停止时事件)

1. 基本布局-- 使用for遍历出列表并添加draggable 属性设置为 true,把元素设置为可拖放

vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第1张图片
vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第2张图片

展示效果:此时元素可拖动
vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第3张图片

2. 添加拖动开始事件dragstart,拖动结束事件dragenter

vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第4张图片
展示效果:拖拽a到c的位置
vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第5张图片

3. 2中视觉上拖拽不明显,添加拖动时候原始数据隐藏(opacity: 0;),拖宅结束后释放隐藏元素到最新位置

  • dragstart方法中添加,class名称来隐藏原始原素
  setTimeout(() => {
        e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
        console.log(7,e.target)
    }, 0)
  • 元素拖拽结束,dragend方法中释放元素
e.target.classList.remove('moveing')
  • dragover方法,增加视觉感这个博主总结的挺详细的)
function dragover(e) {
    console.log(e.dataTransfer)
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
}

✏️ 九宫格拖拽

拖懂逻辑相同,直接复制一份代码,css样式修改下
vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第6张图片

vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第7张图片
vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第8张图片

展示效果

vue3+ts+element-plus管理系统实际开发之H5 拖放事件实现一个拖拉拽_第9张图片

✏️ 完整代码

<template>
    <div class="dragH5">
        <div class="item" v-for="(item, i) in drag.list" :key="item.id" draggable="true" @dragstart="dragstart($event, i)"
            @dragenter="dragenter($event, i)" @dragend="dragend" @dragover="dragover">
            {{ item.name }}
        </div>
        <div class="box-card">
            <div class="item" v-for="(item, i) in drag.list2" :key="item.id" draggable="true" @dragstart="dragstart2($event, i)"
            @dragenter="dragenter2($event, i)" @dragend="dragend2" @dragover="dragover2">
            {{ item.name }}
           </div>
        </div>
    </div>
</template>
<script setup>
import { reactive } from 'vue'
const drag = reactive({
    list: [
        { name: 'a', id: 1 },
        { name: 'b', id: 2 },
        { name: 'c', id: 3 },
        { name: 'd', id: 4 },
        { name: 'e', id: 5 },
    ],
    list2: [
        { name: 'a', id: 11 },
        { name: 'b', id: 12 },
        { name: 'c', id: 13 },
        { name: 'd', id: 14 },
        { name: 'e', id: 15 },
        { name: 'f', id: 16 },
        { name: 'g', id: 17 },
        { name: 'h', id: 18 },
        { name: 'i', id: 19 },
        { name: 'j', id: 110 },
        { name: 'k', id: 111 },
        { name: 'l', id: 112 },
    ]
})
// 列表拖拽
let dragIndex = 0//记录原始拖拽元素下标

function dragstart(e, index) {
    e.stopPropagation()//方法阻止事件冒泡
    dragIndex = index//找到当前拖动元素下标
    setTimeout(() => {
        e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
        console.log(7,e.target)
    }, 0)
}
function dragenter(e, index) {//拖拉进入当前节点时触发当前节点
    e.preventDefault()//阻止默认活动
    // 拖拽到原位置时不触发
    if (dragIndex !== index) {
        const source = drag.list[dragIndex];//找到当前拖动元素原始列表中位置
        drag.list.splice(dragIndex, 1);//删除原始位置
        drag.list.splice(index, 0, source);//添加到新的位置
        dragIndex = index   // 更新节点位置
    }
}
function dragover(e) {
    console.log(e.dataTransfer)
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
}
function dragend(e) {//元素拖拽结束
    e.target.classList.remove('moveing')//元素拖拽结束,去掉设置透明状态的class
}
//九宫格使用
let dragIndex2 = 0//记录原始拖拽元素下标
function dragstart2(e, index) {
    e.stopPropagation()//方法阻止事件冒泡
    dragIndex = index//找到当前拖动元素下标
    setTimeout(() => {
        e.target.classList.add('moveing')//元素正处于拖拽中时候,原始原素设置为透明状态
        console.log(7,e.target)
    }, 0)
}
function dragenter2(e, index) {//拖拉进入当前节点时触发当前节点
    e.preventDefault()//阻止默认活动
    // 拖拽到原位置时不触发
    if (dragIndex !== index) {
        const source = drag.list[dragIndex];//找到当前拖动元素原始列表中位置
        drag.list.splice(dragIndex, 1);//删除原始位置
        drag.list.splice(index, 0, source);//添加到新的位置
        dragIndex = index   // 更新节点位置
    }
}
function dragover2(e) {
    console.log(e.dataTransfer)
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
}
function dragend2(e) {//元素拖拽结束
    e.target.classList.remove('moveing')//元素拖拽结束,去掉设置透明状态的class
}
</script>

<style lang="scss" scoped>
.dragH5{
    overflow-y: scroll;
    height: calc(100vh - 49px);
}
// 列表拖拽
.item {
    width: 200px;
    height: 40px;
    line-height: 40px;
    // background-color: #f5f6f8;
    background-color: skyblue;
    text-align: center;
    margin: 10px;
    color: #fff;
    font-size: 18px;
}

.container {
    position: relative;
    padding: 0;
}

.moveing {
    opacity: 0;
}


// 卡片拖拽
.box-card {
  width: 480px;
  height: 500px;
  display: flex;
  margin-left: 20px;
  flex-wrap: wrap;
  box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
  .item{
    width: 100px;
    height: 50px;
    margin-left: 20px;
  }
}
</style>

你可能感兴趣的:(vue3+ts专栏,vue.js,前端,typescript)