基于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 相关文章推荐
一个js拖拽的效果类和dom-drag.js浅析
Jul 17 Javascript
jquery选择器(常用选择器说明)
Sep 28 Javascript
JS中使用sort结合localeCompare实现中文排序实例
Jul 23 Javascript
贴近用户体验的Jquery日期、时间选择插件
Aug 19 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
Nov 30 Javascript
javascript运动效果实例总结(放大缩小、滑动淡入、滚动)
Jan 08 Javascript
JavaScript中定义对象原型的两种使用方法
Dec 15 Javascript
详解Angular 4.x NgTemplateOutlet
May 24 Javascript
Node.js 8 中的重要新特性
Jun 28 Javascript
jQuery判断自定义属性data-val用法示例
Jan 07 jQuery
wx-charts 微信小程序图表插件的具体使用
Aug 18 Javascript
JavaScript实现前端网页版倒计时
Mar 24 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
第十三节 对象串行化 [13]
2006/10/09 PHP
利用 fsockopen() 函数开放端口扫描器的实例
2017/08/19 PHP
Jquery下的26个实用小技巧(jQuery tips, tricks &amp; solutions)
2010/03/01 Javascript
js实现获取div坐标的方法
2015/11/16 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
又一款js时钟!transform实现时钟效果
2016/08/15 Javascript
详解Javascript中prototype属性(推荐)
2016/09/03 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
jQuery ui autocomplete选择列表被Bootstrap模态窗遮挡的完美解决方法
2016/09/23 Javascript
微信小程序 css使用技巧总结
2017/01/09 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
js实现3D旋转效果
2020/08/18 Javascript
Python单元测试框架unittest简明使用实例
2015/04/13 Python
利用Python生成文件md5校验值函数的方法
2017/01/10 Python
python生成式的send()方法(详解)
2017/05/08 Python
PyChar学习教程之自定义文件与代码模板详解
2017/07/17 Python
python dataframe astype 字段类型转换方法
2018/04/11 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
浅谈python 中类属性共享的问题
2019/07/02 Python
Python搭建Spark分布式集群环境
2019/07/05 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
Matplotlib使用Cursor实现UI定位的示例代码
2020/03/12 Python
pyecharts调整图例与各板块的位置间距实例
2020/05/16 Python
Python flask路由间传递变量实例详解
2020/06/03 Python
python模块如何查看
2020/06/16 Python
Windows下pycharm安装第三方库失败(通用解决方案)
2020/09/17 Python
Expedia韩国官网:亚洲发展最快的在线旅游门户网站
2018/02/26 全球购物
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
惠普香港官方商店:HP香港
2019/04/30 全球购物
导游的职业规划书范文
2013/12/27 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
小学校园文化建设汇报材料
2014/08/19 职场文书
医德考评自我评价
2014/09/14 职场文书
个人党性分析总结
2015/03/05 职场文书
导游词之麻姑仙境
2019/11/18 职场文书