基于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 相关文章推荐
Prototype ObjectRange对象学习
Jul 19 Javascript
jquery jqPlot API 中文使用教程(非常强大的图表工具)
Aug 15 Javascript
json原理分析及实例介绍
Nov 29 Javascript
两种常用的javascript数组去重方法思路及代码
Mar 26 Javascript
高效率JavaScript编写技巧整理
Aug 23 Javascript
JS实现左右无缝轮播图代码
May 01 Javascript
JavaScript制作颜色反转小游戏
Sep 25 Javascript
JS动态计算移动端rem的解决方案
Oct 14 Javascript
Vue.js计算属性computed与watch(5)
Dec 09 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
Mar 24 Javascript
详解ES6系列之私有变量的实现
Nov 21 Javascript
vue使用screenfull插件实现全屏功能
Sep 17 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
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
2013/02/06 PHP
php cURL和Rolling cURL并发方式比较
2013/10/30 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
JavaScript Archive Network 集合
2007/05/12 Javascript
jQuery.Autocomplete实现自动完成功能(详解)
2010/07/13 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
2014/01/12 Javascript
深入探寻javascript定时器
2015/01/02 Javascript
JavaScript表单焦点自动切换代码
2016/07/24 Javascript
基于JavaScript实现鼠标向下滑动加载div的代码
2016/08/31 Javascript
Vue.js实现拖放效果的实例
2016/09/30 Javascript
详解Sea.js中Module.exports和exports的区别
2017/02/12 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
详解用webpack2搭建angular2的项目
2017/06/22 Javascript
模块化react-router配置方法详解
2019/06/03 Javascript
laypage+SpringMVC实现后端分页
2019/07/27 Javascript
jquery弹窗时禁止body滚动条滚动的例子
2019/09/21 jQuery
JavaScript数组排序功能简单实现
2020/05/14 Javascript
python基础教程之对象和类的实际运用
2014/08/29 Python
python实现linux下使用xcopy的方法
2015/06/28 Python
python中Matplotlib实现绘制3D图的示例代码
2017/09/04 Python
Python中的Django基本命令实例详解
2018/07/15 Python
python爬取微信公众号文章
2018/08/31 Python
解决pip install xxx报错SyntaxError: invalid syntax的问题
2018/11/30 Python
python并发编程多进程 互斥锁原理解析
2019/08/20 Python
python 计算积分图和haar特征的实例代码
2019/11/20 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
django有哪些好处和优点
2020/09/01 Python
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
2019/04/26 HTML / CSS
PHP开发工程师面试问题集锦
2012/11/01 面试题
网络安全类面试题
2015/08/01 面试题
《登鹳雀楼》教学反思
2014/04/09 职场文书
小学生我的梦想演讲稿
2014/08/21 职场文书
市场督导岗位职责
2015/04/10 职场文书
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫