基于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 timers计时器简单应用说明
Oct 28 Javascript
yepnope.js 异步加载资源文件
Sep 08 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
May 10 Javascript
js 自定义个性下拉选择框示例
Aug 20 Javascript
Javascript URI 解析介绍
Mar 15 Javascript
jQuery选择器用法实例详解
Dec 17 Javascript
简述jQuery ajax的执行顺序
Jan 05 Javascript
微信小程序 实例应用(记账)详解
Sep 28 Javascript
js实现分页功能
May 24 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
Jun 13 Javascript
Vue实现双向绑定的原理以及响应式数据的方法
Jul 02 Javascript
Vue toFixed保留两位小数的3种方式
Oct 23 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对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
深入理解PHP之OpCode原理详解
2016/06/01 PHP
PHP数组实例详解
2016/06/26 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
jQuery live( type, fn ) 委派事件实现
2009/10/11 Javascript
jQuery使用技巧简单汇总
2013/04/18 Javascript
jquery必须知道的一些常用特效方法及使用示例(整理)
2013/06/24 Javascript
jQuery后代选择器用法实例
2014/12/23 Javascript
jQuery动画与特效详解
2015/02/01 Javascript
基于 webpack2 实现的多入口项目脚手架详解
2017/06/26 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
2017/08/07 Javascript
vue 使用Jade模板写html,stylus写css的方法
2018/02/23 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
python中执行shell命令的几个方法小结
2014/09/18 Python
Python快速排序算法实例分析
2017/11/29 Python
Python实现定时精度可调节的定时器
2018/04/15 Python
好的Python培训机构应该具备哪些条件
2018/05/23 Python
pandas计算最大连续间隔的方法
2019/07/04 Python
Python中zip()函数的简单用法举例
2019/09/02 Python
Python 使用元类type创建类对象常见应用详解
2019/10/17 Python
Python 解析库json及jsonpath pickle的实现
2020/08/17 Python
Python logging自定义字段输出及打印颜色
2020/11/30 Python
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
amazeui页面分析之登录页面的示例代码
2020/08/25 HTML / CSS
美国电子产品折扣网站:Daily Steals
2017/05/20 全球购物
第一范式(1NF)、第二范式(2NF)和第三范式(3NF)之间的区别是什么?
2016/04/28 面试题
小学数学教学反思
2014/02/02 职场文书
应届毕业生求职信
2014/05/26 职场文书
市场推广策划方案
2014/06/02 职场文书
资产运营委托书范本
2014/10/16 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
如何制定销售人员薪酬制度?
2019/07/09 职场文书
Python手拉手教你爬取贝壳房源数据的实战教程
2021/05/21 Python
Oracle 多表查询基本语法实例
2022/04/18 Oracle
Oracle中DBLink的详细介绍
2022/04/29 Oracle