基于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 相关文章推荐
jquery控制listbox中项的移动并排序
Nov 12 Javascript
js 代码优化点滴记录
Feb 19 Javascript
js查错流程归纳
May 04 Javascript
JavaSacript中charCodeAt()方法的使用详解
Jun 05 Javascript
Javascript中实现String.startsWith和endsWith方法
Jun 10 Javascript
jQuery图片轮播实现并封装(一)
Dec 03 Javascript
浅谈react 同构之样式直出
Nov 07 Javascript
原生JS实现 MUI导航栏透明渐变效果
Nov 07 Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 Javascript
JavaScript 如何计算文本的行数的实现
Sep 14 Javascript
微信小程序:报错(in promise) MiniProgramError
Oct 30 Javascript
vue data有值,但是页面{{}} 取不到值的解决
Nov 09 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中执行cmd命令的方法
2014/10/11 PHP
ThinkPHP提示错误Fatal error: Allowed memory size的解决方法
2015/02/12 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
2017/01/16 PHP
JavaScript中的Screen屏幕对象
2008/01/16 Javascript
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
js取滚动条的尺寸的函数代码
2011/11/30 Javascript
用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例
2013/06/25 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
js拼接html注意问题示例探讨
2014/07/14 Javascript
推荐4个原生javascript常用的函数
2015/01/12 Javascript
jquery 构造函数在表单提交过程中修改数据
2015/05/25 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
2015/10/13 Javascript
Angular.JS利用ng-disabled属性和ng-model实现禁用button效果
2017/04/05 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
关于vue中的ajax请求和axios包问题
2018/04/19 Javascript
原生JS实现动态加载js文件并在加载成功后执行回调函数的方法
2020/12/30 Javascript
微信小程序如何调用图片接口API并居中显示
2019/06/29 Javascript
JS图片预加载三种实现方法解析
2020/05/08 Javascript
vue实现导航菜单和编辑文本的示例代码
2020/07/04 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
Python 专题二 条件语句和循环语句的基础知识
2017/03/19 Python
浅析python的优势和不足之处
2018/11/20 Python
redis数据库及与python交互用法简单示例
2019/11/01 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
2020/02/07 Python
Python 实现向word(docx)中输出
2020/02/13 Python
Python异常继承关系和自定义异常实现代码实例
2020/02/20 Python
Python正则表达式如何匹配中文
2020/05/27 Python
中国电视购物:快乐购
2017/02/04 全球购物
日本食品网上商店:JaponShop.com
2017/11/28 全球购物
介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)
2014/10/31 面试题
决心书标准格式
2014/03/11 职场文书
基层党支部公开承诺书
2014/05/29 职场文书
关爱残疾人标语
2014/06/25 职场文书
2015年收银工作总结范文
2015/04/01 职场文书
分析mysql中一条SQL查询语句是如何执行的
2021/06/21 MySQL
Springboot配置suffix指定mvc视图的后缀方法
2021/07/03 Java/Android