Vue组件设计之多列表拖拽交换排序功能实现

作者:aiguangyuan 时间:2024-04-27 15:49:28 

在前端开发中,拖拽排序是一种提升用户体验非常好的方式,常见的场景有单列表拖拽排序,多列表拖拽交换排序,比如以下这种效果:

Vue组件设计之多列表拖拽交换排序功能实现

 下面将以这种效果为例,设计一个组件。

1. 安装所需依赖

npm install vuedraggable --save

本例中目前所用的版本为:2.20.0

2. 组件设计实现

<template>
   <div class="dnd-list">
       <div class="dnd-list-aside" :style="{width:width1 }" >
           <h3>{{ list1Title }}</h3>
           <draggable :list="list1" group="article" class="drag-area" :set-data="setData">
               <div :key="element.id" v-for="element in list1" class="list-complete-item">
                   <div class="list-complete-item-handle1">
                       {{ element.id }} {{ element.title }} [{{ element.author }}]
                   </div>
                   <div style="position:absolute;right:0px">
                       <span style="float:right;margin-top:-20px;margin-right:5px;" @click="deleteItem(element)">
                           <i style="color: #ff4949" class="el-icon-delete" />
                       </span>
                   </div>
               </div>
           </draggable>
       </div>
       <div class="dnd-list-aside" :style="{width:width2}">
           <h3>{{ list2Title }}</h3>
           <draggable :list="list2" group="article" class="drag-area">
               <div :key="element.id" v-for="element in list2" class="list-complete-item">
                   <div class="list-complete-item-handle2" @click="pushItem(element)">
                       {{ element.id }}  {{ element.title }} [{{ element.author }}]
                   </div>
               </div>
           </draggable>
       </div>
   </div>
</template>
<script>
import draggable from "vuedraggable";
export default {
   name: "DndList",
   components: { draggable },
   props: {
       list1: {
           type: Array,
           default() {
               return [];
           },
       },
       list2: {
           type: Array,
           default() {
               return [];
           },
       },
       list1Title: {
           type: String,
           default: "list1",
       },
       list2Title: {
           type: String,
           default: "list2",
       },
       width1: {
           type: String,
           default: "48%",
       },
       width2: {
           type: String,
           default: "48%",
       },
   },
   methods: {
       // 是否在列表一
       isNotInList1(v) {
           return this.list1.every((k) => v.id !== k.id);
       },
       // 是否在列表二
       isNotInList2(v) {
           return this.list2.every((k) => v.id !== k.id);
       },
       // 删除列表项
       deleteItem(element) {
           for (const item of this.list1) {
               if (item.id === element.id) {
                   const index = this.list1.indexOf(item);
                   this.list1.splice(index, 1);
                   break;
               }
           }
           if (this.isNotInList2(element)) {
               this.list2.unshift(element);
           }
       },
       // 点击切换列表项
       pushItem(element) {
           for (const item of this.list2) {
               if (item.id === element.id) {
                   const index = this.list2.indexOf(item);
                   this.list2.splice(index, 1);
                   break;
               }
           }
           if (this.isNotInList1(element)) {
               this.list1.push(element);
           }
       },
       // 拖拽交换时
       setData(dataTransfer) {
           // 解决火狐问题
           // 详见 : https://github.com/RubaXa/Sortable/issues/1012
           dataTransfer.setData("Text", "");
       },
   },
};
</script>
<style lang="scss" scoped>
.dnd-list {
   background: #fff;
   padding-bottom: 40px;
   &:after {
       content: "";
       display: table;
       clear: both;
   }
   .dnd-list-aside {
       float:left;
       padding-bottom: 30px;
       &:first-of-type {
           margin-right: 2%;
       }
       .drag-area{
           margin-top: 15px;
           min-height: 50px;
           padding-bottom: 30px;
       }
   }
}
.list-complete-item {
   cursor: pointer;
   position: relative;
   font-size: 14px;
   padding: 5px 12px;
   margin-top: 4px;
   border: 1px solid #bfcbd9;
   transition: all 1s;
}
.list-complete-item-handle1 {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
   margin-right: 50px;
}
.list-complete-item-handle2 {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
   margin-right: 20px;
}
.list-complete-item.sortable-chosen {
   background: #4ab7bd;
}
.list-complete-item.sortable-ghost {
   background: #30b08f;
}
.list-complete-enter,.list-complete-leave-active {
   opacity: 0;
}
</style>

3. 组件使用示例

<template>
   <div class="box">
       <DndList :list1="list1" :list2="list2" :list1Title="list1Title" :list2Title="list2Title"></DndList>
   </div>
</template>
<script>
import DndList from "@/components/DndList";
export default {
   components:{
       DndList:DndList
   },
   data() {
       return {
           list1:[
               {id:1,title:"《西游记》",author:"吴承恩"},
               {id:2,title:"《红楼梦》",author:"曹雪芹"},
               {id:3,title:"《水浒传》",author:"施耐庵"},
               {id:4,title:"《三国演义》",author:"罗贯中"},
               {id:5,title:"《名人传》",author:"罗曼罗兰"},
               {id:6,title:"《钢铁是怎样炼成的》",author:"奥斯特洛夫斯基"},
           ],
           list2:[
               {id:7,title:"《鲁宾逊漂流记》",author:"笛福"},
               {id:8,title:"《格列佛游记》",author:"约翰斯威夫特"},
               {id:9,title:"《繁星春水》",author:"冰心"},
           ],
           list1Title:"我的图书收藏",
           list2Title:"已读完的图书"
       };
   }
}
</script>
<style scoped>
.box{
   width:600px;
   margin:20px;
   padding:10px;
   background:#fff;
}
</style>

来源:https://blog.csdn.net/weixin_40629244/article/details/130482372

标签:vue,拖拽,排序
0
投稿

猜你喜欢

  • asp GetString的用法

    2008-06-12 13:46:00
  • 深入透析样式表滤镜(上)

    2011-06-14 09:48:40
  • Python安装Imaging报错:The _imaging C module is not installed问题解决方法

    2021-05-19 06:09:39
  • Python之列表的append()方法最容易踩的坑

    2022-05-14 18:56:53
  • sqlserver 数据库连接字符串中的可选项收集

    2011-10-24 19:48:37
  • 兼容主流浏览器的JS复制内容到剪贴板

    2024-04-30 08:52:57
  • 解决MySQL8.0安装第一次登陆修改密码时出现的问题

    2024-01-21 16:19:49
  • python利用有道翻译实现"语言翻译器"的功能实例

    2021-08-21 02:47:38
  • Vue双向绑定原理及实现方法

    2024-05-10 14:16:55
  • np.dot()函数的用法详解

    2023-06-14 02:12:21
  • MySQL 修改数据库名称的一个新奇方法

    2024-01-16 00:56:59
  • python使用itchat库实现微信机器人(好友聊天、群聊天)

    2023-07-12 10:38:39
  • python使用matplotlib绘图时图例显示问题的解决

    2022-11-13 16:59:47
  • python线程池的四种好处总结

    2023-01-27 11:09:55
  • python通过伪装头部数据抵抗反爬虫的实例

    2022-03-11 09:56:04
  • 下拉列表两级连动的新方法(二)

    2009-06-04 18:22:00
  • 关于ThinkPhp 框架表单验证及ajax验证问题

    2023-11-15 06:33:05
  • SQLite数据库管理相关命令的使用介绍

    2024-01-27 12:41:00
  • 浅谈Python 函数式编程

    2022-09-03 20:38:07
  • Python中偏函数用法示例

    2022-10-13 18:48:26
  • asp之家 网络编程 m.aspxhome.com