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 相关文章推荐
jquery常用方法及使用示例汇总
Nov 08 Javascript
详解Javascript动态操作CSS
Dec 08 Javascript
使用jQuery实现更改默认alert框体
Apr 13 Javascript
JavaScript中constructor()方法的使用简介
Jun 05 Javascript
jQuery带进度条全屏图片轮播特效代码分享
Jun 28 Javascript
jQuery遍历DOM节点操作之filter()方法详解
Apr 14 Javascript
javascript基础练习之翻转字符串与回文
Feb 20 Javascript
bootstrap选项卡扩展功能详解
Jun 14 Javascript
微信小程序onLaunch异步,首页onLoad先执行?
Sep 20 Javascript
如何自定义微信小程序tabbar上边框的颜色
Jul 09 Javascript
es6 for循环中let和var区别详解
Jan 12 Javascript
Vue ElementUI实现:限制输入框只能输入正整数的问题
Jul 31 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中apc缓存使用示例
2013/12/25 PHP
php静态文件返回304技巧分享
2015/01/06 PHP
使用php+swoole对client数据实时更新(一)
2016/01/07 PHP
php使用yield对性能提升的测试实例分析
2019/09/19 PHP
JQuery团队打造的javascript单元测试工具QUnit介绍
2010/02/26 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
jQuery文本框(input textare)事件绑定方法教程
2013/04/24 Javascript
js正则表达式的使用详解
2013/07/09 Javascript
JSON格式化输出
2014/11/10 Javascript
js实现简单折叠、展开菜单的方法
2015/08/28 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
javascript性能优化之分时函数的介绍
2018/03/28 Javascript
Angular模版驱动表单的使用总结
2018/05/05 Javascript
加快Vue项目的开发速度的方法
2018/12/12 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
详解React 条件渲染
2020/07/08 Javascript
[02:03]完美世界DOTA2联赛10月30日赛事集锦
2020/10/31 DOTA
利用Python脚本实现ping百度和google的方法
2017/01/24 Python
Django中使用celery完成异步任务的示例代码
2018/01/23 Python
python实现简易动态时钟
2018/11/19 Python
django主动抛出403异常的方法详解
2019/01/04 Python
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
浅谈Python类中的self到底是干啥的
2019/11/11 Python
Python datetime模块使用方法小结
2020/06/18 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
2020/09/16 Python
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
奢华的意大利皮革手袋:Bene Handbags
2019/10/29 全球购物
互联网创业计划书写作技巧攻略
2014/03/23 职场文书
安全协议书
2014/04/23 职场文书
研发工程师岗位职责
2014/04/28 职场文书
意外死亡赔偿协议书
2014/10/14 职场文书
珍爱生命主题班会
2015/08/13 职场文书
详解vue中v-for的key唯一性
2021/05/15 Vue.js
如何利用python创作字符画
2022/06/25 Python