vue实现拖拽排序

        在业务中列表拖拽排序是比较常见的需求,常见的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值是iddata: {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.hqwc.cn/news/128129.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【代码随想录】LC 209. 长度最小的子数组

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 三、知识风暴 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记&#xff0c;如有侵权&#xff0c;立即删除。 一、题目 1、原题链接 209. 长度最小的子数组 2、题目…

Python接口自动化测试 —— Selenium+pytest+数据驱动

主流自动化框架 selenium &#xff1a;web端自动化框架 &#xff0c;&#xff08;行业里面最核心的框架&#xff09; appium &#xff1a;手机app端框架 requests &#xff1a;接口测试 selenium 工具类封装 selenium提供了很多方法供我们去完成网页元素的操作&#xff0c; …

二、Excel VBA 简单使用

Excel VBA 从入门到出门一、Excel VBA 是个啥&#xff1f;二、Excel VBA 简单使用 &#x1f44b;Excel VBA 简单使用 ⚽️1. 如何在Excel中手动编写VBA代码⚽️2. 如何在 Excel 中运行 VBA 代码⚽️3. 如何在Excel中记录VBA代码⚽️4. 如何在Excel中编辑录制的VBA代码⚽️5. 如…

nginx-proxy反向代理缓存

介绍&#xff1a; 反向代理缓存&#xff0c;类似于动静分离&#xff0c;即通过nginx代理服务器根据客户端发送的url请求&#xff0c;去后台服务器获取数据&#xff0c;将静态数据缓存到nginx代理服务器上&#xff0c;并配置有过期时间&#xff0c;当客户端下次以相同的url请求…

屏幕分辨率:PC / 手机 屏幕常见分辨率,前端如何适配分辨率

一、常见的PC屏幕分辨率 序号水平像素点数和垂直像素点数也被称为常见显示器11366 768720p 或 HD Ready常见于笔记本电脑和低端桌面显示器21920 10801080p 或 Full HD / 全高清高端笔记本电脑和中高档台式机32560 14402K 分辨率常见于高端笔记本电脑和高端台式机43840 216…

基于SSM+Vue的订餐系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Spring Cloud父子容器及容器的启动源码

1.前言 接触过Spring Cloud都知道&#xff0c;服务启动的时候会先启动Spring Cloud容器加载bootstrap.yml的配置&#xff0c;然后再启动我们常说的Spring容器&#xff0c;那么为什么需要父子容器&#xff0c;父容器又是在什么地方进行创建的呢&#xff1f; 2. 为什么需要父子…

JS-前端在dom中预览pdf等文件

1、将pdf等文件显示到dom元素中预览 pdf文件可以是blob、url、file类型等只要使用URL.createObjectURL(file)全部转为URL即可使用无需借助任何插件&#xff0c;只需要使用<object></object>标签即可实现 1.1、html <template><div class"home"…

云原生Kubernetes:K8S集群kubectl命令汇总

目录 一、理论 1.概念 2. kubectl 帮助方法 3.kubectl 子命令使用分类 4.使用kubectl 命令的必要环境 5.kubectl 详细命令 一、理论 1.概念 kubectl是一个命令行工具&#xff0c;通过跟 K8S 集群的 API Server 通信&#xff0c;来执行集群的管理工作。 kubectl命令是操…

对于无法直接获取URL的数据爬虫

在爬学校安全教育题库的时候发现题库分页实际上执行了一段js代码&#xff0c;如下图所示 点击下一页时是执行了函数doPostBack&#xff0c;查看页面源码如下 点击下一页后这段js提交了一个表单&#xff0c;随后后端返回对应数据&#xff0c;一开始尝试分析获取对应两个参数&a…

CCF CSP认证 历年题目自练Day25

题目 试题编号&#xff1a; 201403-3 试题名称&#xff1a; 命令行选项 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   请你写一个命令行分析程序,用以分析给定的命令行里包含哪些选项。每个命令行由若干个字符串组成,它们之间…

Unity基于种子与地块概率的开放世界2D地图生成

public class BuildingGen : MonoBehaviour {public int[] Building;//存储要生成的地块代码public int[] Probability;//存储概率public double seed;public int width 100;public int height 100;public float noiseScale 0.1f; //噪声缩放倍数private int[,] frequencyM…