【开发记录】vue3实现列表拖拽排序,如何阻止放下后,元素回落?

一、问题描述

写了一个列表的拖拽排序,但遇到一个问题,就是拖拽放下后,html元素总会有一个回落的默认效果,这个会影响排序效果。

二、解决

其实,最后解决的办法,也很简单,就是在dragover事件处理中,去除默认,也就是e.preventDefault();

js 复制代码
 const onDragOver = (e: any, index: number) => {
    e.preventDefault();
    // ....
 }

三、最后,记录一下完整的代码实现

vue3 复制代码
<template>
  <div>
    <div class="card-list">
      <div
        class="card-item"
        :class="{'drag-over': dragOverIndex === index, 'active': dragData.index == index}"
        v-for="(item, index) in dataList"
        :key="item.cocosData.id"
        :id="item.cocosData.id"
        draggable="true"
        @dragstart.stop="onDragStart($event, index)"
        @dragover.stop="onDragOver($event, index)"
        @dragend.stop="onDragend"
      >
        <span>{{ item }}</span>
      </div>
    </div>
  </div>
</template>

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

export default defineComponent({
    name: "DragSort",
    setup(props) {
        const dataList = ref<string[]>([
            "字母A",
            "字母B",
            "字母D",
            "p",
        ]);
        
        const dragData = ref<any>({});
        const onDragStart = (e: any, index: number) => {
          dragData.value = {
            index,
          }
        }
        const dragOverIndex = ref(-1);
        const onDragOver = (e: any, index: number) => {
          e.preventDefault();
          if (dragData.value.index != index) {
            dragOverIndex.value = index;
          } else {
            dragOverIndex.value = -1;
          }
        }
        const onDragend = (e: any) => {
          e.preventDefault();
          const dragIndex = dragData.value.index;
          console.log('onDragend', dragIndex, dragOverIndex.value);
          if (dragIndex != dragOverIndex.value && dragOverIndex.value != -1) {
            const dragItem = _.cloneDeep(cocosdata.value["children"][dragIndex]);
            console.log('dragItem', dragItem);
            if (dragOverIndex.value > dragIndex) {
              cocosdata.value["children"].splice(dragOverIndex.value + 1, 0, dragItem);
              cocosdata.value["children"].splice(dragIndex, 1);
            } else {
              cocosdata.value["children"].splice(dragIndex, 1);
              cocosdata.value["children"].splice(dragOverIndex.value, 0, dragItem);
            }
          }
          dragOverIndex.value = -1;
          dragData.value = {};
        }
        
        return {
          dataList,
          onDragStart,
          onDragOver,
          dragOverIndex,
          onDragend,
          dragData,
        };
    },
});

</script>

<style lang="less" scoped>
.card-list {
  margin-top: 10px;
  .card-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid transparent;
    position: relative;
    &.active {
      background-color: #f2f2f2;
    }
    &.drag-over {
      background-color: #ddd;
      border: 1px solid #aaa;
    }
    span {
      cursor: pointer;
    }
  }
}
</style>

四、最后

欢迎各位来用下我用了近2年,搞的一款网页编辑器,一定会让你感到惊讶的,哈哈!

相关推荐
Bs_MoneyMagnet1 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计
计算机魔术师1 小时前
Dario Amodei 发文呼吁为前沿 AI 降速并提出三点计划
前端
计算机魔术师2 小时前
OpenAI的AI代理偷偷给RubyGems下毒,我们却毫无察觉
前端
甲维斯2 小时前
0代码,0建模,3句话开发一个3D游戏!
前端·游戏·游戏开发
IT_陈寒2 小时前
Vue的响应式更新把我坑惨了,原来问题出在这
前端·人工智能·后端
tingke2 小时前
别再堆 AGENTS.md 了:前端团队的 Agent 上下文分层落地指南
前端
李明卫杭州3 小时前
React 复合事件系统对比解析
前端·javascript·react.js
葡萄城技术团队3 小时前
SpreadJS V19.2 新特性揭秘:FILTERXML 函数
前端
行者全栈架构师4 小时前
Spring Boot 接入 MaxKey 单点登录:6 个内部系统,一次登录全通行
java·vue.js·后端
袋鼠云数栈UED团队4 小时前
AI Coding 方法论分析:同一个需求 SpecKit 、 Superpowers、 MattpocockSkills 不同设计
前端·aigc·ai编程