vue实现列表拖拽排序的功能


Posted in Javascript onNovember 02, 2020

在日常开发中,特别是管理端,经常会遇到要实现拖拽排序的效果;这里提供一种简单的实现方案。

此例子基于vuecli3

首先,我们先了解一下js原生拖动事件:

在拖动目标上触发事件 (源元素):

  • ondragstart - 用户开始拖动元素时触发
  • ondrag - 元素正在拖动时触发
  • ondragend - 用户完成元素拖动后触发

释放目标时触发的事件:

  • ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
  • ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
  • ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
  • ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

 基于js的原生拖拽事件,本次实现的拖拽排序的原理大概是:鼠标按住列表某一项开始拖动时触发ondragstart事件,将该拖动项用变量记录下来;

接着拖拽过程中,该拖动项经过列表其他项时,触发ondragenter事件,同样记录该拖动项最后经过的列表其他项的数据,最后在ondragend 事件中

将数组列表删掉一开始ondragstart事件记录的拖动项,并将删掉的数据插入ondragenter事件最后记录的位置,完成拖动排序。

 具体代码如下:

<template>
  <div class="test_wrapper" @dragover="dragover($event)">
    <transition-group class="transition-wrapper" name="sort">
      <div v-for="(item) in dataList" :key='item.id' class="sort-item"
        :draggable="true"
        @dragstart="dragstart(item)"
        @dragenter="dragenter(item,$event)"
        @dragend="dragend(item,$event)"
        @dragover="dragover($event)"
      >
        {{ item.label }}
      </div>
    </transition-group>
  </div>
</template>

<script lang="ts">
  import {Vue, Component, Prop, Watch} from "vue-property-decorator";
  import { addWebsite } from '@/api'
  @Component({
    components: {}
  })
  export default class Test extends Vue {

    oldData: any = null; // 开始排序时按住的旧数据
    newData: any = null; // 拖拽过程的数据

    // 列表数据
    dataList:any = [
      { id:1,label:'测试一号' },
      { id:2,label:'测试二号' },
      { id:3,label:'测试三号' },
      { id:4,label:'测试四号' },
    ];

    dragstart(value: any) {
      this.oldData = value
    }

    // 记录移动过程中信息
    dragenter(value: any, e: any) {
      this.newData = value
      e.preventDefault()
    }

    // 拖拽最终操作
    dragend(value: any, e: any) {
      if (this.oldData !== this.newData) {
        let oldIndex = this.dataList.indexOf(this.oldData)
        let newIndex = this.dataList.indexOf(this.newData)
        let newItems = [...this.dataList]
        // 删除老的节点
        newItems.splice(oldIndex, 1)
        // 在列表中目标位置增加新的节点
        newItems.splice(newIndex, 0, this.oldData)
        this.dataList = [...newItems]
      }
    }


    // 拖动事件(主要是为了拖动时鼠标光标不变为禁止)
    dragover(e: any) {
      e.preventDefault()
    }


  };
</script>

另外

为了实现拖动的动画效果,这里用到了transition-group组件,如上面代码显示,将transition-group组件的属性name设为‘sort';并添加以下代码;

.sort-move {
      transition: transform 0.3s;
    }

       注意:为了让transition有效果出现,v-for渲染的数据列表必须有key属性,且该key属性不可设为index; 

最终效果如下:

vue实现列表拖拽排序的功能

以上就是vue实现列表拖拽排序的功能的详细内容,更多关于vue 拖拽排序的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
文字幻灯片
Jun 26 Javascript
JavaScript 高级语法介绍
Jun 15 Javascript
ASP.NET jQuery 实例10 动态修改hyperlink的URL值
Feb 03 Javascript
javascript SpiderMonkey中的函数序列化如何进行
Dec 05 Javascript
JS 模态对话框和非模态对话框操作技巧汇总
Apr 15 Javascript
js捕获鼠标滚轮事件代码
Dec 16 Javascript
以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题
Nov 13 Javascript
js常用DOM方法详解
Feb 04 Javascript
Vue组件库发布到npm详解
Feb 17 Javascript
Vue项目中最新用到的一些实用小技巧
Nov 06 Javascript
微信小程序实现倒计时功能
Nov 19 Javascript
react项目从新建到部署的实现示例
Feb 19 Javascript
用vue写一个日历
Nov 02 #Javascript
在vue中使用vant TreeSelect分类选择组件操作
Nov 02 #Javascript
vant自定义二级菜单操作
Nov 02 #Javascript
JavaScript动态生成表格的示例
Nov 02 #Javascript
JavaScript实现图片放大预览效果
Nov 02 #Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
Nov 02 #Javascript
在antd4.0中Form使用initialValue操作
Nov 02 #Javascript
You might like
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
2018/08/10 PHP
jquery.simple.tree插件 更简单,兼容性更好的无限树插件
2010/09/03 Javascript
javascript SpiderMonkey中的函数序列化如何进行
2012/12/05 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
自带气泡提示的vue校验插件(vue-verify-pop)
2017/04/07 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
Vue 仿QQ左滑删除组件功能
2018/03/12 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
vue中$refs的用法及作用详解
2018/04/24 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
JavaScript实现密码强度实时验证
2020/03/18 Javascript
[01:01]青春无憾,一战成名——DOTA2全国高校联赛开启
2018/02/25 DOTA
[01:03:42]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[19:54]夜魇凡尔赛茶话会 第一期02:看图识人
2021/03/11 DOTA
Python中协程用法代码详解
2018/02/10 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
python解压TAR文件至指定文件夹的实例
2019/06/10 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
python+pygame实现坦克大战
2019/09/10 Python
英国高档时尚男装购物网站:MR PORTER
2016/08/09 全球购物
华为慧通笔试题
2016/04/22 面试题
运动会致辞稿50字
2014/02/04 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
酒店端午节活动方案
2014/08/26 职场文书
师德师风个人总结
2015/02/06 职场文书
2015年学生会个人工作总结
2015/04/09 职场文书
不服劳动仲裁起诉书
2015/05/20 职场文书
活动主持人开场白
2015/05/28 职场文书
爱国主义影片观后感
2015/06/18 职场文书
傅雷家书读书笔记
2015/06/29 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
2016大学先进团支部事迹材料
2016/03/01 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书