Vue组件设计-多列表拖拽交换排序

news2024/9/28 3:19:44

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

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

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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487298.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多模态的过渡态——latent modal

背景&#xff1a; 随着大模型的推进&#xff0c;单模态的大模型已经无法很好的满足现实工作的需要。很多科研团队和机构开始多模态的研究&#xff0c;多模态的几种机构在前面的文章已经介绍过&#xff0c;这部分不做过多介绍。最理想的多模态应该就是没有模态&#xff0c;单一…

持续集成/持续交付——JenkinsFile详细使用教程

JenkinsFile详细使用教程 一、BlueOcean1、BlueOcean 概念2、BlueOcean 特性3、BlueOcean 安装 二、Pipeline 简介1、Jenkins Pipeline 概念2、Jenkinsfile 语法类型&#xff1a;3、采用Jenkins 任务页面输入a. Jenkins中创建一个 pipeline 任务b. Definition 中选择 Pipeline …

电脑提示msvcp140.dll丢失的解决方法,msvcp140.dll丢失修复教程

msvcp140.dll是Microsoft Visual C Redistributable所需的一个动态链接库文件&#xff0c;它包含了Visual C运行库中的一些函数和类库。这个文件通常出现在Windows操作系统中&#xff0c;用于支持使用Visual C编写的程序的正常运行。如果系统缺少或损坏了这个文件&#xff0c;可…

计算机组成原理 4.2.1存储芯片连接

连接原理 主存储器 通过数据总线、地址总线和控制总线和CPU相连数据总线的位数正比于数据传输率地址总线的位数决定可寻址的最大地址空间控制总线(读/写)指出总线周期的类型和本次输入/输出完成的时刻 但是实际中存储芯片往往很小难以满足地址和数据的位数需求&#xff0c;此…

如何在云服务器上搭建ChatGLM

摘录&#xff1a;ChatGPT重新点燃了AI&#xff0c;然后OpenAI却没有向我们开放ChatGPT&#xff0c;虽然有些人通过了一下手段注册了账号&#xff0c;但是不久就被OpenAI拉入了黑名单。3月份我国的百度也推出了和ChatGPT对标的文言一心&#xff0c;随后阿里也推出了自己的文本对…

李雨浛:在数据、网络与民意之间——用计算社会科学方法探讨数字媒体与可持续未来 | 提升之路系列(八)...

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

创建并使用shell脚本

1&#xff0c;查询 bash解释器 所在位置 创建前&#xff0c;我们需要先知道 bash 解释器所在的位置&#xff0c;以方便在头部写声明。一般位置是在 /bin/bash 但是有的是在 /usr/bin/bash &#xff0c;所以需要查找一下。 文件位置查找命令&#xff1a;whereis xxx rootarmb…

Probabilistic and Geometric Depth: Detecting Objects in Perspective 论文学习

论文地址&#xff1a;Probabilistic and Geometric Depth: Detecting Objects in Perspective Github 地址&#xff1a;Probabilistic and Geometric Depth: Detecting Objects in Perspective 1. 解决了什么问题&#xff1f; 3D 目标检测在许多应用中发挥着重要作用&#xf…

分析的四个维度

我们都听过这句格言“数据是新石油”——一种宝贵、丰富的资源&#xff0c;只有提炼后才有用。然而&#xff0c;最引人注目但又令人望而生畏的比较之一是将船只送入海洋进行石油勘探。有些会失败&#xff0c;有些会有重大发现。 深海勘探和钻探取决于精确测绘和对海底的清晰认…

【计算机网络】图解内容分发网络 CDN

【计算机网络】图解内容分发网络 CDN 参考资料&#xff1a; 用了CDN就一定比不用更快吗&#xff1f; 什么是内容分发网络 高性能利器&#xff1a;CDN我建议你好好学一下&#xff01; 文章目录 【计算机网络】图解内容分发网络 CDN一、CDN 概述1.1、什么是 CDN1.2、为什么需要 …

数字化转型导师坚鹏:数字化转型背景下的企业人力资源管理

企业数字化转型背景下的企业人力资源管理 课程背景&#xff1a; 很多企业存在以下问题&#xff1a; 不清楚企业数字化转型目前的发展阶段与重要应用&#xff1f; 不知道企业数字化转型给企业人力资源管理带来哪些机遇与挑战&#xff1f; 不知道企业数字化转型背景下如何…

SpringBoot 项目如何实现动态配置多数据源?

简介&#xff1a; dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。 其支持 Jdk 1.7, SpringBoot 1.4.x 1.5.x 2.x.x。 特性&#xff1a; 支持 数据源分组 &#xff0c;适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。支持…

认识JavaBean

什么是JavaBean? JavaBean是指符合特定规范以及定义的Java类&#xff0c;通常用于封装数据&#xff0c;提供访问数据的方法和属性&#xff0c;并且可以被其他程序重用。它具有以下特点&#xff1a; 遵循特定编程规范&#xff1a;JavaBean必须要遵循JavaBean编程规范&#xff…

分层领域模型相关总结(DO/PO/VO/BO/DTO/Query等概念)

分层领域模型(DO/PO/VO/BO/DTO/Query等概念) 1. 为什么会有这么多O的概念&#xff1f; 各种分层概念的提出都是为了解耦&#xff0c;增加逻辑/代码的复用&#xff0c;便于后期维护/开发&#xff0c;提高团队开发效率&#xff1b;but&#xff0c;过多的细分也会使得开发过程相对…

Chrome 113 发布,默认启用 WebGPU

经过四周时间开发&#xff0c;Chrome 113 稳定版正式推出&#xff0c;新版本包括用于视频电话会议的 AV1 视频编码、WebGPU&#xff0c;以及其他增强功能。 默认启用 WebGPU WebGPU 是用于 Web 的新 API&#xff0c;它使用了现代的硬件功能&#xff0c;允许在 GPU 上进行渲染和…

Unable to import maven project: See logs for details错误的多种解决方法

文章目录 1. 复现错误2. 分析错误3. 解决问题3.1 解决方法一3.2 解决方法二 4. 补充说明 1. 复现错误 今天从gitlab上下载完项目后&#xff0c;无法启动项目&#xff0c;留意到右下角的Evnet Log&#xff0c;点开如下图所示&#xff1a; 即Unable to import maven project: See…

vue-element-admin快速搭建后台模板

快速搭建后台模板 环境以及会出现的问题安装目录结构基本配置路由配置 环境以及会出现的问题 node版本17.0.0 python版本2.7.10&#xff08;node-sass依赖&#xff09; 运行项目报错Error: error:0308010C:digital envelope routines::unsupport 请看这篇文章 https://blog.cs…

FM33A048B I2C

I2C 模块实现MCU 与外部I2C 接口器件之间的同步通信&#xff0c;硬件实现串并转换。支持I2C 的主机模式&#xff0c;不支持从机模式和多主机模式。 特点&#xff1a; ⚫ 只支持I2C 主机模式, 不支持从机模式和多主机模式 ⚫ 支持7 位或10 位从机地址 ⚫ 传输速度支持标准模式(1…

Java面试题总结 | Java面试题总结10- Feign和设计模式模块(持续更新)

文章目录 Feign项目中如何进行通信Feign原理简述 设计模式spring用到的设计模式项目的场景中运用了哪些设计模式写单例的时候需要注意什么工厂模式的理解设计模式了解么工厂设计模式单例设计模式代理设计模式策略模式**模板方法模式**观察者模式**适配器模式**观察者模式**适配…

TimeScaleDB食用手册

TimescaleDB食用手册 一 TimescaleDB介绍 TimescaleDB是一种用于处理时间序列数据的开源时序数据库&#xff0c;它是PostgreSQL的扩展。它可以处理大量的时间序列数据&#xff0c;并且支持SQL查询和连续聚合功能。 1.TimescaleDB的优点 分布式架构&#xff1a;TimescaleDB利…