基于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修改客户端注册表的方法
Aug 09 Javascript
js中的replace方法使用介绍
Oct 28 Javascript
jquery showModelDialog的使用方法示例详解
Nov 19 Javascript
jquery获取复选框被选中的值
Apr 10 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
Apr 14 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
Oct 02 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
Feb 29 Javascript
node.js cookie-parser 中间件介绍
Jun 06 Javascript
XMLHttpRequest Level 2 使用指南
Aug 26 Javascript
js仿手机页面文件下拉刷新效果
Oct 14 Javascript
JS基于正则表达式的替换操作(replace)用法示例
Apr 28 Javascript
JS字符串补全方法padStart()和padEnd()
May 27 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中Session的概念
2006/10/09 PHP
php表单敏感字符过滤类
2014/12/08 PHP
PHP调用微博接口实现微博登录的方法示例
2018/09/22 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
用javascript实现页面打印的三种方法
2007/03/05 Javascript
根据json字符串生成Html的一种方式
2013/01/09 Javascript
javascript当中的代码嗅探扩展原生对象和原型(prototype)
2013/01/11 Javascript
浅谈JavaScript事件的属性列表
2015/03/01 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
react native实现往服务器上传网络图片的实例
2017/08/07 Javascript
vue2.0 自定义组件的方法(vue组件的封装)
2018/06/05 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
JS代码触发事件代码实例
2020/01/02 Javascript
[58:11]守擂赛第二周擂主赛 DeMonsTer vs Leopard
2020/04/28 DOTA
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
深入理解python中的浅拷贝和深拷贝
2016/05/30 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
pytorch 数据集图片显示方法
2018/07/26 Python
画pytorch模型图,以及参数计算的方法
2019/08/17 Python
Python 字符串类型列表转换成真正列表类型过程解析
2019/08/26 Python
基于TensorBoard中graph模块图结构分析
2020/02/15 Python
python 实现关联规则算法Apriori的示例
2020/09/30 Python
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
广州御银科技股份有限公司试卷(C++)
2016/11/04 面试题
哪些情况下不应该使用索引
2015/07/20 面试题
啤酒节策划方案
2014/05/28 职场文书
材料物理专业求职信
2014/09/01 职场文书
软件研发工程师岗位职责
2014/09/30 职场文书
幼儿教师辞职信范文
2015/03/02 职场文书
采购员岗位职责范本
2015/04/07 职场文书
如何写好开幕词?
2019/06/24 职场文书
python 命令行传参方法总结
2021/05/25 Python
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python
Win11 22H2 2022怎么更新? 获得Win1122H22022版本升级技巧
2022/09/23 数码科技