基于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调用后台servlet方法实例
Jun 09 Javascript
让checkbox不选中即将选中的checkbox不选中
Jul 11 Javascript
js封装可使用的构造函数继承用法分析
Jan 28 Javascript
基于jQuery实现最基本的淡入淡出效果实例
Feb 02 Javascript
学习JavaScript设计模式(多态)
Nov 25 Javascript
微信小程序 教程之注册程序
Oct 17 Javascript
JS刷新父窗口的几种方式小结(推荐)
Nov 09 Javascript
JavaScript中boolean类型之三种情景实例代码
Nov 21 Javascript
JavaScript BASE64算法实现(完美解决中文乱码)
Jan 10 Javascript
Javascript中document.referrer隐藏来源的方法
Jan 16 Javascript
javascript基础练习之翻转字符串与回文
Feb 20 Javascript
Vue实现剪贴板复制功能
Dec 31 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 MPDF中文乱码的解决方式
2015/12/08 PHP
PHP查询分页的实现代码
2017/06/09 PHP
php中请求url的五种方法总结
2017/07/13 PHP
jQuery移除tr无效的解决方法(tr是动态添加)
2014/09/22 Javascript
JavaScript中最简洁的编码html字符串的方法
2014/10/11 Javascript
根据配置文件加载js依赖模块
2014/12/29 Javascript
js实现网页右上角滑出会自动消失大幅广告的方法
2015/02/27 Javascript
JavaScript 七大技巧(一)
2015/12/13 Javascript
Nodejs中的this详解
2016/03/26 NodeJs
jQuery判断checkbox选中状态
2016/05/12 Javascript
js canvas实现擦除效果示例代码
2017/04/26 Javascript
Angular实现预加载延迟模块的示例
2017/10/12 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
详解React服务端渲染从入门到精通
2019/03/28 Javascript
重学JS之显示强制类型转换详解
2019/06/30 Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
2019/08/20 Javascript
iview实现动态表单和自定义验证时间段重叠
2021/01/10 Javascript
[00:31]DOTA2荣耀之路7:Miracle-空血无敌斩
2018/05/31 DOTA
python中字典dict常用操作方法实例总结
2015/04/04 Python
Python语言描述KNN算法与Kd树
2017/12/13 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
Pytorch中的variable, tensor与numpy相互转化的方法
2019/10/10 Python
python下载库的步骤方法
2019/10/12 Python
python爬虫中url管理器去重操作实例
2020/11/30 Python
远程Wi-Fi宠物监控相机:Petcube
2017/04/26 全球购物
寻找完美的房车租赁:RVShare
2019/02/23 全球购物
幼师自我鉴定
2014/02/01 职场文书
《学会合作》教学反思
2014/04/12 职场文书
骨干教师考核方案
2014/05/09 职场文书
群众路线领导班子四风对照检查材料
2014/09/27 职场文书
群众路线四风对照检查材料
2014/11/04 职场文书
党纪处分决定书
2015/06/24 职场文书
基于Python和openCV实现图像的全景拼接详细步骤
2021/10/05 Python
Python可视化学习之seaborn调色盘
2022/02/24 Python
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js
Win10多屏显示如何设置?Win10电脑多屏显示设置操作方法
2022/07/07 数码科技