基于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功能函数(2009-06-04更新)
Jun 04 Javascript
使用jQuery时Form表单元素ID和name命名大忌
Mar 06 Javascript
通过url查找a元素应用案例
Apr 29 Javascript
使用text方法获取Html元素文本信息示例
Sep 01 Javascript
jquery实现简单实用的打分程序实例
Jul 23 Javascript
JS+CSS实现精美的二级导航效果代码
Sep 17 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
Jun 10 Javascript
让编辑器支持word复制黏贴、截屏的js代码
Oct 17 Javascript
Vue axios 中提交表单数据(含上传文件)
Jul 06 Javascript
详解ajax的data参数错误导致页面崩溃
Apr 30 Javascript
JavaScript页面倒计时功能完整示例
May 15 Javascript
动态规划之使用备忘录来改进Javascript函数
Apr 07 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单例模式应用详解
2013/06/03 PHP
php输入数据统一类实例
2015/02/23 PHP
详解PHP版本兼容之openssl调用参数
2018/07/25 PHP
Javascript attachEvent传递参数的办法
2009/12/14 Javascript
javascript中的一些注意事项 更新中
2010/12/06 Javascript
nodejs npm install全局安装和本地安装的区别
2014/06/05 NodeJs
用js判断是否为360浏览器的实现代码
2015/01/15 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
jQuery实现TAB风格的全国省份城市滑动切换效果代码
2015/08/24 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
Node.JS利用PhantomJs抓取网页入门教程
2017/05/19 Javascript
如何通过非数字与字符的方式实现PHP WebShell详解
2017/07/02 Javascript
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
2018/05/10 Javascript
JS实现的对象去重功能示例
2019/06/04 Javascript
非常漂亮的js烟花效果
2020/03/10 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
在Windows系统上搭建Nginx+Python+MySQL环境的教程
2015/12/25 Python
python使用ddt过程中遇到的问题及解决方案【推荐】
2018/10/29 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
调试Django时打印SQL语句的日志代码实例
2019/09/12 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
python 30行代码实现蚂蚁森林自动偷能量
2021/02/08 Python
css3背景_动力节点Java学院整理
2017/07/11 HTML / CSS
美国办公用品购物网站:Quill.com
2016/09/01 全球购物
Revolution Beauty美国官网:英国知名化妆品网站
2018/07/23 全球购物
英文版网络工程师求职信
2013/10/28 职场文书
医药个人求职信范文
2014/01/29 职场文书
2014年关于两会精神的心得体会
2014/03/17 职场文书
小学优秀教育工作者事迹材料
2014/05/09 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
国家税务局领导班子对照检查材料思想汇报
2014/10/04 职场文书
医院领导班子四风问题对照检查材料
2014/10/26 职场文书
事业单位考察材料范文
2014/12/25 职场文书