vue实现拖拽排序

news2024/11/26 13:42:23

        在业务中列表拖拽排序是比较常见的需求,常见的JS拖拽库有Sortable.js,Vue.Draggable等,大多数同学遇到这种需求也是更多的求助于这些JS库,其实,使用HTML原生的拖放事件来实现拖拽排序并不复杂,结合Vue的transition-group,还能快速的给排序添加过渡动画。

HTML5拖放api

1. 设置元素为可拖放

为了使元素可拖动,把 draggable 属性设置为 true :

<div draggable="true">能被拖放的元素</div>
2. 拖放事件

拖放涉及到两种元素,一种是被拖拽元素(源对象),一种是放置区元素(目标对象)。如下图所示,按住A元素往B元素拖拽,A元素即为源对象,B元素即为目标对象。

触发对象事件名称说明
在拖动目标上触发事件ondragstart用户开始拖动元素时触发
ondrag元素正在拖动时触发
ondragend用户完成元素拖动后触发
释放目标时触发的事件ondragenter当被鼠标拖动的对象进入其容器范围内时触发此事件
ondragover当某被拖动的对象在另一对象容器范围内拖动时触发此事件
ondragleave当被鼠标拖动的对象离开其容器范围内时触发此事件
ondrop当在一个拖动过程中,释放鼠标键时触发此事件

需要注意的是:dragenterdragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们要在这两个拖放事件中使用preventDefault来阻止浏览器的默认行为;而且目标对象想要变成可释放区域,必须设置dragoverdrop 事件处理程序属性。

基于vue的拖拽排序

先不考虑排序动画,解释一下实现思路:

  • 由于拖动是实时的,所以没有使用drop而是使用了dragenter触发排序。
  • 在源对象开始被拖拽时记录其索引dragIndex,当它进入目标对象时(对应dragenter事件),将其插入到目标对象的位置。
  • 其中dragenter方法中有一个判断this.dragIndex !== index(index为当前目标对象的索引),这是因为源对象同时也是目标对象,当没有这个判断时,源对象开始被拖拽时就会立刻触发自身的dragenter事件,这是不合理的。

 

有动画的拖拽排序

        把HTML的ul元素改为transition-group,在CSS中新增一个过渡transition: transform .3s;,就可以实现有动画的拖拽排序

改造成可复用的组件

<template>
  <transition-group name="drag" class="list" tag="ul">
    <li
      @dragstart="dragstart(index)"
      @dragenter="dragenter($event, index)"
      @dragend="dragend"
      @dragover.prevent
      :draggable="draggable"
      v-for="(item, index) in list"
      :key="item.id"
      class="list-item"
    >
      <slot :scope="item" :index="index"></slot>
    </li>
  </transition-group>
</template>

<script>
export default {
  name: "DragList",
  model: {
    prop: "data",
    event: "change",
  },
  props: {
    // 唯一的key值是id
    data: {
      type: Array,
      default: () => [],
    },
    draggable: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dragIndex: "",
    };
  },
  computed: {
    list() {
      return [...this.data];
    },
  },
  methods: {
    // 拖拽元素(源对象)
    dragstart(index) {
      if (!this.draggable) return;
      this.dragIndex = index;
    },
    // 目标元素
    dragenter(e, index) {
      e.preventDefault();
      if (!this.draggable) return;
      // 避免源对象触发自身的dragenter事件
      if (this.dragIndex !== index) {
        const moving = this.list[this.dragIndex]; // 拖拽元素
        this.list.splice(this.dragIndex, 1); // 删除拖拽元素
        this.list.splice(index, 0, moving); // 在目标元素中追加拖拽元素
        // 排序变化后目标对象的索引变成源对象的索引
        this.dragIndex = index;
        this.$emit("change", this.list);
      }
    },
    dragover(e) {
      e.preventDefault();
    },
    dragend() {
      this.$emit("dragend");
    },
  },
};
</script>

<style lang="less" scoped>
.list {
  list-style: none;
  .drag-move {
    transition: transform 0.3s;
  }
  .list-item {
    // cursor: move;
    // width: 300px;
    // background: #ea6e59;
    // border-radius: 4px;
    // color: #fff;
    // margin-bottom: 6px;
    // height: 50px;
    // line-height: 50px;
    // text-align: center;
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【运维笔记】Docker 安装Kibana-7.4.0(在线Docker版)

一、准备工作&#xff1a; Centos 7.5 安装 Docker-24.0.6 详细步骤&#xff08;避坑版&#xff09;&#xff1a; https://blog.csdn.net/seesun2012/article/details/133674191注意1&#xff1a;本文的命令使用的是 root 用户登录执行&#xff0c;不是 root 的话所有命令前面…

山西电力市场日前价格预测【2023-10-09】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-09&#xff09;山西电力市场全天平均日前电价为575.84元/MWh。其中&#xff0c;最高日前电价为1500.00元/MWh&#xff0c;预计出现在17: 30-20: 00。最低日前电价为218.27元/MWh&#x…

go的面向对象学习

文章目录 面向对象编程(上)1.问题与解决思路2.结构体1》Golang语言面向对象编程说明2》结构体与结构体变量(实例/对象)的关系的示意图3》入门案例(using struct to solve the problem of cat growing) 3.结构体的具体应用4.创建结构体变量和访问结构体字段5.struct类型的内存分…

Snowflake:一家由数据驱动的生成式人工智能公司

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;从长远来看&#xff0c;生成式人工智能只会进一步增加数据的重要性。 &#xff08;2&#xff09;尽管宏观环境面临挑战&#xff0c;但Snowflake(SNOW)仍然保持着强劲的增长率。 …

Map,Set和哈希表的使用

目录 两种模型 Map的使用 Map接口方法的使用 注意事项 Set的使用 哈希表 冲突 如何避免冲突 在我们日常生活中,会进行一些查找操作,比如根据姓名查询考试成绩,根据姓名查询联系方式等在查找是进行一些插入和删除操作,即动态查找. 而Map和Set是一种适合动态查找的集合容…

springboot整合thymeleaf模板引擎

1.什么是thyeleaf模板引擎 Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。 是新一代 Java 模板引擎&#xff0c;它支持 HTML 原型&#xff0c;其文件后缀为“.html”&#xff0c;因此它可以直接被浏览器打开&#xff0c;此时浏览器会忽略未定义的 Thymeleaf 标签…

C语言:字符字符串

目录 字符 字符串 输出各字符串 输出各类型长度——strlen函数返回字符串长度&#xff0c;需指定头文件 字符 a;char ch z;// char ch "z"; // err 字符类型只能是单引号// char ch zh; // err 字符类型只能是单个字符 字符串 这种由双引号&#xff08;Doub…

SpringBoot+Vue3外卖项目构思

SpringBoot的学习&#xff1a; SpringBoot的学习_明里灰的博客-CSDN博客 实现功能 前台 用户注册&#xff0c;邮箱登录&#xff0c;地址管理&#xff0c;历史订单&#xff0c;菜品规格&#xff0c;购物车&#xff0c;下单&#xff0c;菜品浏览&#xff0c;评价&#xff0c;…

软考程序员考试大纲(2023)

文章目录 前言一、考试说明1.考试目标2.考试要求3&#xff0e;考试科目设置 二、考试范围考试科目1&#xff1a;计算机与软件工程基本知识1&#xff0e;计算机科学基础2&#xff0e;计算机系统基础知识3&#xff0e;系统开发和运行知识4&#xff0e;网络与信息安全基础知识5&am…

你的librosa和scikit-learn打架了吗?

被这个问题困扰好久&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我的原来版本librosa0.7.1 和 scikit-learn1.3.1 一直拆了按&#xff0c;按…

好物周刊#19:开源指北

https://github.com/cunyu1943/JavaPark https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. Vditor 一款浏览器端的 Markdown 编辑器&#xff0c;支持所见即所得、…

Android---Class 对象在执行引擎中的初始化过程

一个 class 文件被加载到内存中的步骤如下图所示&#xff1a; 装载 装载是指 Java 虚拟机查找 .class 文件并生成字节流&#xff0c;然后根据字节流创建 java.lang.Class 对象的过程。 1. ClassLoader 通过一个类的全限定名&#xff08;包名类名&#xff09;来查找 .class 文件…

10款录屏软分析与选择使用,只看这篇文章就轻松搞定所有,高清4K无水印录屏,博主UP主轻松选择

录屏软件整理 如下为录屏软件&#xff0c;通过思维导图展示分析介绍&#xff1a; https://www.drawon.cn/template/details/6522bd5e0dad9029a0b528e1 如下为整理的录屏软件列表 名称产地价格支持的平台下载地址说明OBS国外免费开源windows/linux/machttps://obsproject.co…

好物周刊#12:计算机考研资料

https://cunyu1943.github.io https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. JEECG BOOT 低代码开发平台 一款基于代码生成器的低代码开发平台&#xff01;前后…

Charles:移动端抓包 / windows客户端 iOS手机 / 手机访问PC本地项目做调试

一、背景描述 1.1、本文需求&#xff1a;移动端进行抓包调试 1.2、理解Charles可以做什么 Charles是一款跨平台的网络代理软件&#xff0c;可以用于捕获和分析网络流量&#xff0c;对HTTP、HTTPS、HTTP/2等协议进行调试和监控。使用Charles可以帮助开发人员进行Web开发、调试…

数字三角形加强版题解(组合计数+快速幂+逆元)

Description 一个无限行的数字三角形&#xff0c;第 i 行有 i 个数。第一行的第一个数是 1 &#xff0c;其他的数满足如下关系&#xff1a;如果用 F[i][j] 表示第 i 行的第 j 个数&#xff0c;那么 F[i][j]A∗F[i−1][j]B∗F[i−1][j−1] &#xff08;不合法的下标的数为 0 &a…

【jvm--方法区】

文章目录 1. 栈、堆、方法区的交互关系2. 方法区的内部结构3. 运行时常量池4. 方法区的演进细节5. 方法区的垃圾回收 1. 栈、堆、方法区的交互关系 方法区的基本理解&#xff1a; 方法区&#xff08;Method Area&#xff09;与 Java 堆一样&#xff0c;是各个线程共享的内存区…

openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw

文章目录 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw93.1 编译oracle_fdw93.2 使用oracle_fdw93.3 常见问题93.4 注意事项 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw openGauss的fdw实现的功能是各个openGauss数据库及…

ChatGPT讲Mysql优化技巧 附体验地址

ChatGPT讲Mysql优化技巧 体验地址附文末 面具选择互联网写手 提问&#xff1a;Mysql优化 回答 MySQL优化是一个广泛讨论的话题&#xff0c;因为好的MySQL性能可以极大地提高应用程序的效率。在这里&#xff0c;我将向你介绍一些常见的MySQL优化技巧&#xff1a; 使用正确的…

软件测试基础 - 测试覆盖率

一、覆盖率概念 覆盖率是用来度量测试完整性的一个手段&#xff0c;是测试技术有效性的一个度量。分为&#xff1a;白盒覆盖、灰盒覆盖和黑盒覆盖&#xff1b;测试用例设计不能一味追求覆盖率&#xff0c;因为测试成本随覆盖率的增加而增加。 覆盖率&#xff08;至少被执行一次…