Vue组件设计之多列表拖拽交换排序功能实现
作者:aiguangyuan 时间:2024-04-27 15:49:28
在前端开发中,拖拽排序是一种提升用户体验非常好的方式,常见的场景有单列表拖拽排序,多列表拖拽交换排序,比如以下这种效果:
下面将以这种效果为例,设计一个组件。
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,拖拽,排序
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
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
![](https://img.aspxhome.com/file/2023/6/103546_0s.jpg)
python利用有道翻译实现"语言翻译器"的功能实例
2021-08-21 02:47:38
![](https://img.aspxhome.com/file/2023/7/84137_0s.png)
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
![](https://img.aspxhome.com/file/2023/8/62898_0s.jpg)
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