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 相关文章推荐
脚本吧 - 幻宇工作室用到js,超强推荐base.js
Dec 23 Javascript
基于jquery点击自以外任意处,关闭自身的代码
Feb 10 Javascript
jquery仿百度经验滑动切换浏览效果
Apr 14 Javascript
浅析JS异步加载进度条
May 05 Javascript
总结Javascript中的隐式类型转换
Aug 24 Javascript
第一次接触神奇的Bootstrap
Oct 14 Javascript
Mongoose经常返回e11000 error的原因分析
Mar 29 Javascript
vue组件学习教程
Sep 09 Javascript
利用nvm管理多个版本的node.js与npm详解
Nov 02 Javascript
Vue2.0 实现页面缓存和不缓存的方式
Nov 12 Javascript
JS异步宏队列与微队列原理区别详解
Jul 02 Javascript
ztree+ajax实现文件树下载功能
May 18 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开发文件系统实例讲解
2006/10/09 PHP
php中把美国时间转为北京时间的自定义函数分享
2014/07/28 PHP
php生成短域名函数
2015/03/23 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
php的socket编程详解
2016/11/20 PHP
js实现权限树的更新权限时的全选全消功能
2009/02/17 Javascript
通过身份证号得到出生日期和性别的js代码
2009/11/23 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
2012/09/14 Javascript
精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
2016/07/01 Javascript
jQuery实现下拉菜单(内容为时间)的实时更新及图表的随动更新的方法
2016/07/07 Javascript
AngularJS中isolate scope的用法分析
2016/11/22 Javascript
javascript 判断一个对象为数组的方法
2017/05/03 Javascript
浅谈angular4生命周期钩子
2017/09/05 Javascript
vue中的provide/inject的学习使用
2018/05/09 Javascript
微信小程序 (地址选择1)--选取搜索地点并显示效果
2019/12/17 Javascript
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
[01:00:17]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第二场 1月25日
2021/03/11 DOTA
Python爬取qq空间说说的实例代码
2018/08/17 Python
Python unittest 自动识别并执行测试用例方式
2020/03/09 Python
Pyecharts 中Geo函数常用参数的用法说明
2021/02/01 Python
CSS3实现时间轴效果
2016/07/11 HTML / CSS
html5的新玩法——语音搜索
2013/01/03 HTML / CSS
巴西网上药房:onofre
2016/11/21 全球购物
Funko官方商店:源自美国,畅销全球搪胶收藏玩偶
2018/09/15 全球购物
美国中西部家用医疗设备商店:Med Mart(轮椅、踏板车、升降机等)
2019/04/26 全球购物
ParcelABC西班牙:包裹运送和快递服务
2019/12/24 全球购物
公司拓展活动方案
2014/02/13 职场文书
初中军训感想300字
2014/03/05 职场文书
学校端午节活动方案
2014/08/23 职场文书
购房协议书范本
2014/10/02 职场文书
学校师德师风整改方案
2014/10/28 职场文书
2014年减负工作总结
2014/12/10 职场文书
初中教师德育工作总结2015
2015/05/12 职场文书
社区安置帮教工作总结2015
2015/05/20 职场文书
python基于tkinter制作下班倒计时工具
2021/04/28 Python
CentOS7安装MySQL8的超级详细教程(无坑!)
2022/06/10 Servers