基于Vue实现平滑过渡的拖拽排序功能


Posted in Javascript onJune 12, 2019

最近重读Vue官方文档,在 列表的排序过渡 这一小节,文档提到,<transition-group> 组件有一个特殊的地方,不仅可以实现进入和离开动画,还可以改变定位,官网示例如下:

基于Vue实现平滑过渡的拖拽排序功能 

例子中实现的效果看起来还是非常不错的,这个效果使我想起来另外一个使用场景,之前我在实现一个列表展示需求的时候,PM想让这个列表具有拖动排序的功能,方便他操作(事实上我最后并没有给他做哈哈),拖动的动画跟这个很像,网上搜索一下,类似插件应该很多,那如果我们自己来实现一个,问题在哪里呢?

首先要拖拽元素,记录元素拖拽开始和结束的信息。

将元素由拖拽开始的地方移到拖拽结束地方,这期间,目标元素和目标元素周围的元素要怎么平滑过渡到新的位置。

问题1很好解决,翻一下api,HTML5提供了性能很棒的拖放API,PC端兼容性良好,可直接使用

问题2刚好可以使用上面学到的<transition-group>组件去实现。

拖放API中提到,一个可拖拽的元素,在用户拖拽这一整个流程中,可以通过这个事件去获取你想要的信息:

基于Vue实现平滑过渡的拖拽排序功能 

这里的话,我们选取dragstart去记录下拖拽元素的信息,dragenter去记录此元素拖拽时经过了哪些元素,dragend事件中去做拖拽结束的操作,动画的事情就交给transition-group去做了。

最终实现的效果如下:

基于Vue实现平滑过渡的拖拽排序功能 

demo代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width">
  <title>test</title>
  <style type="text/css">
    .flip-list-move {
    transition: transform 1s;
   }
   .items {
    width: 300px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border: 1px solid red;
   }
  </style>
</head>
<body>
  <div id="content">
   <transition-group name="flip-list">
     <div v-for="item in items" :key="item" draggable="true" class="items" @dragstart="dragstart(item)" @dragenter="dragenter(item)" @dragend="dragend(item)">{{item}}</div>
   </transition-group>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
  <script>
    var vue = new Vue({
     el: '#content',
     data: {
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      oldNum: 0,
      newNum: 0
     },
     created: function created () {
     }, 
     mounted: function mounted () {
     },
     methods: {
      shuffle: function() {
       this.items = _.shuffle(this.items);
      },
      // 记录初始信息
      dragstart: function(value) {
       this.oldNum = value;
      },
      // 做最终操作
      dragend: function(value) {
       if (this.oldNum != this.newNum) {
        let oldIndex = this.items.indexOf(this.oldNum);
        let newIndex = this.items.indexOf(this.newNum);
        let newItems = [...this.items];
        // 删除老的节点
        newItems.splice(oldIndex, 1); 
        // 在列表中目标位置增加新的节点
        newItems.splice(newIndex, 0, this.oldNum);
        // this.items一改变,transition-group就起了作用
        this.items = [...newItems];
       }
      },
      // 记录移动过程中信息
      dragenter: function(value) {
       this.newNum = value;
      }
     }
    }); 
  </script>
</body>
</html>

注:你也可以一遍拖拽一遍更改顺序,不用等dragend再做动画,但是一边拖拽一边做动画的时候看起来眼花缭乱的(仅以这个demo来看是这样的,其他插件可以提供别的解决方法,暂且按下不表)所以我选择用户拖拽停止之后再做动画。

在这一节中,vue官方还介绍了一个叫FLIP的简单的动画队列,有兴趣可以研究一下, FLIP介绍 ,打开这个FLIP你会发现它的示例中有介绍另外一个动画库GASP ,可以实现很酷炫的动画效果,跟FLIP结合使用效果更佳。

总结

以上所述是小编给大家介绍的基于Vue实现平滑过渡的拖拽排序功能,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
Mootools 1.2教程 事件处理
Sep 15 Javascript
JavaScript 拾漏补遗
Dec 27 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 Javascript
jQuery显示和隐藏 常用的状态判断方法
Jan 29 Javascript
javascript+HTML5自定义元素播放焦点图动画
Feb 21 Javascript
jQuery Mobile动态刷新页面样式的实现方法
May 28 Javascript
判断js的Array和Object的实现方法
Aug 29 Javascript
原生JS实现隐藏显示图片 JS实现点击切换图片效果
Jan 27 Javascript
cdn模式下vue的基本用法详解
Oct 07 Javascript
微信小程序功能之全屏滚动效果的实现代码
Nov 22 Javascript
Vue 使用formData方式向后台发送数据的实现
Apr 14 Javascript
Vue + Elementui实现多标签页共存的方法
Jun 12 #Javascript
JavaScript使用面向对象实现的拖拽功能详解
Jun 12 #Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
Jun 12 #jQuery
小程序组件之自定义顶部导航实例
Jun 12 #Javascript
vue项目中将element-ui table表格写成组件的实现代码
Jun 12 #Javascript
React 全自动数据表格组件——BodeGrid的实现思路
Jun 12 #Javascript
详解如何提升JSON.stringify()的性能
Jun 12 #Javascript
You might like
解析PHP中intval()等int转换时的意外异常情况
2013/06/21 PHP
PHP检测用户是否关闭浏览器的方法
2016/02/14 PHP
tp5.1 框架路由操作-URL生成实例分析
2020/05/26 PHP
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
基于jQuery试卷自动排版系统
2010/07/18 Javascript
表格单元格交错着色实现思路及代码
2013/04/01 Javascript
Javascript Ajax异步读取RSS文档具体实现
2013/12/12 Javascript
nodejs导出excel的方法
2015/06/30 NodeJs
Javascript将数值转换为金额格式(分隔千分位和自动增加小数点)
2016/06/22 Javascript
JS获取html元素的标记名实现方法
2016/10/08 Javascript
Vue动态实现评分效果
2017/05/24 Javascript
jQuery实现手势解锁密码特效
2017/08/14 jQuery
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
vue使用高德地图点击下钻上浮效果的实现思路
2019/10/12 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
2020/07/26 Javascript
vue-cli3中配置alias和打包加hash值操作
2020/09/04 Javascript
python实现linux服务器批量修改密码并生成execl
2014/04/22 Python
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
用Python制作简单的朴素基数估计器的教程
2015/04/01 Python
Python使用functools模块中的partial函数生成偏函数
2016/07/02 Python
Python常见字典内建函数用法示例
2018/05/14 Python
使用PyQtGraph绘制精美的股票行情K线图的示例代码
2019/03/14 Python
python实现控制台输出彩色字体
2020/04/05 Python
Bath & Body Works阿联酋:在线购买沐浴和身体用品
2021/02/27 全球购物
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
如何开启linux的ssh服务
2013/06/03 面试题
高中毕业自我鉴定
2013/12/16 职场文书
开业庆典邀请函
2014/01/08 职场文书
新领导上任欢迎词
2014/01/13 职场文书
餐厅楼面主管岗位职责范本
2014/02/16 职场文书
超市创业计划书
2014/09/15 职场文书
小学生思想品德评语
2014/12/31 职场文书
2019年亲子运动会口号
2019/10/11 职场文书
python 制作一个gui界面的翻译工具
2021/05/14 Python
python用tkinter开发的扫雷游戏
2021/06/01 Python
MySQL非空约束(not null)案例讲解
2021/08/23 MySQL