vue实现拖拽(vuedraggable)

实现效果:

左侧往右侧拖动,右侧列表可以进行拖拽排序。

安装引用:

npm install vuedraggable
import draggable from 'vuedraggable'

使用:

data数据:

      componentList: [{groupName: '考试题型',children: [{componentType: 'danxuan',componentName: '单选题',componentIcon: 'icon-danxuan'},{componentType: 'duoxuan',componentName: '多选题',componentIcon: 'icon-duoxuan'},{componentType: 'panduan',componentName: '判断题',componentIcon: 'icon-panduan'}]},{groupName: '信息题',children: [{componentType: 'message',componentName: '姓名',componentIcon: 'icon-xingming'},{componentType: 'message',componentName: '手机',componentIcon: 'icon-shouji'},{componentType: 'message',componentName: '邮箱',componentIcon: 'icon-youxiang'}]}],
questionList:[],

html代码:

左侧代码:   
<el-tabs type="border-card" class="tabs"><el-tab-pane label="题型"><div v-for="(item, index) in componentList" :key="index"><b class="fs-14">{{item.groupName}}</b><draggable@end="end":clone="cloneElement"class="group"v-model="item.children":sort="false" //禁止排序:group="{name: 'component',pull: 'clone', put: false  //不允许其他元素拖拽进此空间}"><div @click="pushComponent(_item)" class="component" v-for="(_item, _index) in item.children" :key="_index"><i class="iconfont mr-8" :class="_item.componentIcon"></i><span>{{_item.componentName}}</span></div></draggable></div></el-tab-pane><el-tab-pane label="题库"><el-treeref="tree"highlight-current:data="treeList"node-key="id":current-node-key="currentNodekey"@node-click="handleNodeClick":load="loadNode":props="props"lazy><span slot-scope="{node}"><el-tooltip v-if="node.label.length>=8"  class="item" effect="dark" :content="node.label" placement="top"><div class="text-ellipsis width-150">{{ node.label }}</div></el-tooltip><div v-else>{{ node.label }}</div></span></el-tree></el-tab-pane></el-tabs>
右侧代码:<div class="content"><el-scrollbar ref="scrollbar" style="height: calc(100vh - 220px)">{{questionList}}<draggableclass="list"forceFallback:animation="200"ghostClass="ghost"handle=".el-icon-rank"v-model="questionList":group="{name: 'component'}"><transition-group class="height-percent-100 display-block"><divclass="item":class="{active: item.active, error: item.error}"v-for="(item, index) in questionList":key="item.uid"><divclass="display-flex ai-flex-start padding-20 pt-14"@click="clickQuestion(item)":id="item.uid"><div class="pt-6 width-40"><b>{{index + 1}}</b></div><div class="flex-1"><div class="display-flex ai-flex-start jc-space-between"><b @click="editTitle(item)" class="width-percent-80 pt-6" style="min-height: 26px" v-if="!item.editTitle">{{item.title}}</b><el-inputtype="textarea"autosize:ref="item.uid"v-elsesize="small"class="width-percent-80"@blur="item.editTitle = false"v-model="item.title"></el-input><span v-if="item.componentType !== 'message'" class="color-info pt-6">( {{item.score}}分 )</span></div><div class="mt-12"><el-inputv-if="item.componentType === 'message'"readonlyplaceholder="请输入"type="textarea"autosizev-model="item.answer"size="small"class="width-percent-80"></el-input><draggable v-model="item.options" handle=".el-icon-d-caret"><transition-group><div v-for="i in item.options" :key="i.value" class="display-flex ai-center jc-space-between pt-4 pb-4"><div class="flex-1 display-flex ai-center"><el-checkboxv-if="item.componentType === 'duoxuan'"v-model="item.answer" :label="i.value">{{  }}</el-checkbox><el-radiov-elsev-model="item.answer":label="i.value" class="mr-0">{{  }}</el-radio><p @click="editOption(i)" v-if="!i.edit" class="margin-0 fs-14 width-percent-80 display-flex ai-center" style="min-height: 32px">{{i.label}}</p><el-inputtype="textarea"autosize@blur="i.edit = false":ref="i.value"v-elsev-model="i.label"size="small"class="width-percent-80"></el-input></div><div class="display-flex ai-center fd-row-reverse color-info width-130"><i class="el-icon-d-caret ml-8 cursor-move"></i><i @click="delOption(item, i.value)" class="ml-10 el-icon-remove-outline cursor-pointer"></i><span class="color-success fs-14" v-if="item.answer.includes(i.value)">( 正确答案 )</span></div></div></transition-group></draggable><div v-if="['danxuan', 'duoxuan'].includes(item.componentType)"><el-button class="pb-0" @click="addOption(item)" type="text" icon="el-icon-plus">添加选项</el-button></div></div></div><div class="display-flex ai-center color-info mt-8"><i class="ml-14 el-icon-rank cursor-move"></i><i @click.stop="copyQuestion(item, index)" class="ml-14 el-icon-document-copy cursor-pointer"></i><i @click.stop="delQuestion(item)" class="ml-14 el-icon-delete cursor-pointer"></i></div></div><div class="errorMessage" v-if="item.error">{{item.errorMessage}}</div></div><div key="empty" v-if="!questionList.length" class="height-percent-100 fd-column display-flex ai-center jc-center"><el-empty description="请点击右侧或拖入题型进行添加题目"></el-empty></div></transition-group></draggable></el-scrollbar></div>

方法:

     /*** 点击组件进行push* @param data* @param type*/pushComponent (data, type = 0) {console.log(data)//type=1:后端给的题库项导入  0:题型项导入this.questionList.push(type ? data : this.cloneElement(data))const newDraggableIndex = this.questionList.length - 1const e = {to: {className: 'pushComponent'},newDraggableIndex}this.end(e)},/*** 拖拽结束* @param e*/end (e) {console.log(e)if (e.to.className !== 'group') {for (const item of this.questionList) {item.active = false}this.questionList[e.newDraggableIndex].active = truethis.$nextTick(() => {document.getElementById(this.questionList[e.newDraggableIndex].uid).scrollIntoView();})}},/*** 拖拽clone* @param item* @returns {any}*/cloneElement (item) {const data = JSON.parse(JSON.stringify(item));console.log(data)data.uid = `${data.componentType}-${Math.floor(Math.random() * 1000000)}`data.title = data.componentNamedata.answer = ''data.active = falsedata.editTitle = falsedata.error = falsedata.errorMessage = ''switch (data.componentType) {case 'danxuan':data.scoreMethod = '1' // 得分方式data.options = [{edit: false,label: '选项1',value: `${data.componentType}-${Math.floor(Math.random() * 1000000)}`},{edit: false,label: '选项2',value: `${data.componentType}-${Math.floor(Math.random() * 1000000)}`}] // 选项data.answer = data.options[0].value // 答案data.score = 10 // 分数data.description = '' // 解析breakcase 'duoxuan':data.scoreMethod = '1'data.options = [{edit: false,label: '选项1',value: `${data.componentType}-${Math.floor(Math.random() * 1000000)}`},{edit: false,label: '选项2',value: `${data.componentType}-${Math.floor(Math.random() * 1000000)}`}]data.answer = [data.options[0].value]data.score = 10data.description = ''breakcase 'panduan':data.scoreMethod = '1'data.options = [{edit: false,label: '是',value: `${data.componentType}-true`},{edit: false,label: '否',value: `${data.componentType}-false`}]data.answer = data.options[0].valuedata.score = 10data.description = ''break}return data},

css:

.tabs {width: 240px;box-shadow: none;border: none;height: 100%;.group {display: grid;grid-gap: 12px;grid-template-columns: repeat(2, 1fr);font-size: 14px;padding: 12px 0;}.component {color: #666666;border-radius: 4px;border: 1px solid #D8D8D8;display: flex;align-items: center;justify-content: center;padding: 8px 0;cursor: pointer;&:hover {color: #1774FF;border-color: #1774FF;}}
}
.content {flex: 1;background-color: #EFF2F4;border-left: 1px solid #DCDFE6;border-right: 1px solid #DCDFE6;padding: 20px 4px 0 20px;.list {height: 100%;margin-right: 16px;.item {padding: 0;border: 1px solid transparent;border-radius: 4px;box-shadow: 0 2px 4px 0 rgba(0,0,0,0.1);background-color: #fff;margin-bottom: 20px;.el-icon-delete,.el-icon-remove-outline {&:hover {color: #F56C6C;}}.el-icon-document-copy {&:hover {color: #3377FF;}}}.errorMessage {color: #FFFFFF;background-color: #F56C6C;padding: 10px 20px;font-size: 14px;border-radius: 0 0 4px 4px;}.active {border-color: #2A5EFF;}.error {border-color: #F56C6C;}}.ghost {background-color: #499BFF;border-radius: 4px;padding: 20px;margin-bottom: 20px;.iconfont {display: none;}span {color: #FFFFFF;}}
}

扩展:

点击题库中的题进行导入:

代码:

<el-tab-pane label="题库"><el-treeref="tree"highlight-current:data="treeList"node-key="id":current-node-key="currentNodekey"@node-click="handleNodeClick":load="loadNode":props=" {label: 'name',value: 'id',isLeaf: 'isLeaf'},"lazy><span slot-scope="{node}"><el-tooltip v-if="node.label.length>=8"  class="item" effect="dark" :content="node.label" placement="top"><div class="text-ellipsis width-150">{{ node.label }}</div></el-tooltip><div v-else>{{ node.label }}</div></span></el-tree>
</el-tab-pane>

方法:

handleNodeClick (node) {if (node.level === 2) {//点击子节点(叶子节点)this.$nextTick(() => {this.$refs.tree.setCurrentKey(node.id)})const data = JSON.parse(JSON.stringify(node))data.answer = JSON.parse(node.answer)data.uid = `${data.componentType}-${Math.floor(Math.random() * 1000000)}`this.pushComponent(data, 1)} else {this.$nextTick(() => {this.$refs.tree.setCurrentKey()})}
},
loadNode (node, resolve) {if (node.level === 0) {this.$api.pxExam.getExamSetList({ name: this.fuzzy }).then(res => {this.treeList = res.map(res => {return {name: res.name,id: res.id,isLeaf: false,level: 1}})return resolve(this.treeList)})}
pushComponent方法通用的(传参不同),上面写的有。

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

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

相关文章

SQLite 的使用

SQLite 是一个轻量级、自包含和无服务器的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于嵌入式系统、移动应用程序和小中型网站。它易于创建、需要的配置较少&#xff0c;并且提供了用于管理和操作数据的强大功能集。本文&#xff0c;我们将带领你…

电路设计(26)——交通信号灯的multism仿真

1.功能要求 使用数字芯片设计一款交通信号灯&#xff0c;使得&#xff1a; 主干道的绿灯时间为60S&#xff0c;红灯时间为45S 次干道的红灯时间为60S&#xff0c;绿灯时间为45S 主、次干道&#xff0c;绿灯的最后5S内&#xff0c;黄灯闪烁 使用数码管显示各自的倒计时时间。 按…

openssl3.2 - 编译 - zlib.dll不要使用绝对路径

文章目录 openssl3.2 - 编译 - 编译时的动态库zlib.dll不要使用绝对路径概述测试zlib特性在安装好的目录中是否正常笔记70-test_tls13certcomp.t80-test_cms.t对测试环境的猜测从头再编译测试安装一次测试一下随便改变位置的openssl用到zlib时是否好使测试一下随便改变位置的op…

Docker Nginx 负载均衡搭建(服务宕机-配置高可用) - 附(Python案例,其它语言同理)

目录 一 . 概要 1. 什么是负载均衡 2. 负载均衡有哪些优势&#xff1f; &#xff08;1&#xff09;应用程序可用性 &#xff08;2&#xff09;应用程序可扩展性 &#xff08;3&#xff09;应用程序安全 &#xff08;4&#xff09;应用程序性能 3 . Nginx负载均衡调度策…

核密度分析

一.算法介绍 核密度估计&#xff08;Kernel Density Estimation&#xff09;是一种用于估计数据分布的非参数统计方法。它可以用于多种目的和应用&#xff0c;包括&#xff1a; 数据可视化&#xff1a;核密度估计可以用来绘制平滑的密度曲线或热力图&#xff0c;从而直观地表…

win系统下安装php8.3版本并配置环境变量的详细教程

本篇文章主要讲解在win系统下安装和配置php8.3版本&#xff0c;并配置环境变量的详细教程。 日期&#xff1a;2024年2月22日 作者&#xff1a;任聪聪 一、下载php8.3版本包 php8.3版本官方下载地址&#xff1a;https://windows.php.net/download#php-8.3 步骤一、打开下载地址…

【Unity】Unity与安卓交互

问题描述 Unity和安卓手机进行交互&#xff0c;是我们开发游戏中最常见的场景。本教程将从一个简单的例子来演示一下。 本教程需要用到Android Studio2021.1.1 1.Android Studio新建一个工程 2.选择Empty Activity 然后点击Next 3.点击Finish完成创建 4.选择File-New-New Mo…

【python 3.9.18】windowns安装版

因为这个版本官方未提供&#xff0c;所以需要自己编译出来&#xff0c;其他没有的版本可以依据下面的进行生成一个exe也可行。 成品&#xff1a; https://gitee.com/greatLong/python-3.9.18/tree/master/python-3.9.18/PCbuild/amd64 1、环境准备 需要使用到 这里面还需要选…

【MATLAB GUI】 5. 图像处理菜单(菜单编辑器)

看B站up主freexyn的freexyn编程实例视频教程系列36Matlab GUI的学习笔记 任务要求设计一个图像处理菜单&#xff0c;实现图像的打开导入、灰度处理、存储等功能 修改过文件名&#xff0c;所以运行的时候会有一点点报错&#xff0c;但是不影响运行 打开工具栏下边的菜单编辑器…

创建一个基于Node.js的实时聊天应用

在当今数字化社会&#xff0c;实时通讯已成为人们生活中不可或缺的一部分。无论是在社交媒体平台上与朋友交流&#xff0c;还是在工作场合中与同事协作&#xff0c;实时聊天应用都扮演着重要角色。与此同时&#xff0c;Node.js作为一种流行的后端技术&#xff0c;为开发者提供了…

CrossOver虚拟机软件2024有哪些功能?最新版本支持哪些游戏?

CrossOver由codewaver公司开发的类虚拟机软件&#xff0c;目的是使linux和Mac OS X操作系统和window系统兼容。CrossOver不像Parallels或VMware的模拟器&#xff0c;而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏&#xff0c;而不…

LangChain支持哔哩哔哩视频总结

是基于LangChain框架下的开发&#xff0c;所以最开始请先 pip install Langchain pip install bilibili-api-python 技术要点&#xff1a; 使用Langchain框架自带的Document loaders 修改BiliBiliLoader的源码&#xff0c;自带的并不支持当前b站的视频加载 源码文件修改&a…

【高德地图】Android高德地图绘制标记点Marker

&#x1f4d6;第4章 Android高德地图绘制标记点Marker ✅绘制默认 Marker✅绘制多个Marker✅绘制自定义 Marker✅Marker点击事件✅Marker动画效果✅Marker拖拽事件✅绘制默认 Infowindow&#x1f6a9;隐藏InfoWindow 弹框 ✅绘制自定义 InfoWindow&#x1f6a9;实现 InfoWindow…

ArcgisForJS如何实现添加含图片样式的点要素?

文章目录 0.引言1.加载底图2.获取点要素的坐标3.添加含图片样式的几何要素4.完整实现 0.引言 ArcGIS API for JavaScript 是一个用于在Web和移动应用程序中创建交互式地图和地理空间分析应用的库。本文在ArcGIS For JavaScript中使用Graphic对象来创建包含图片样式的点要素。 …

MIT-6.824-Lab2,Raft部分笔记|Use Go

文章目录 前记Paper6&#xff1a;RaftLEC5、6&#xff1a;RaftLAB22AtaskHintlockingstructureguide设计与编码 2BtaskHint设计与编码 2CtaskHint question后记 LEC5&#xff1a;GO, Threads, and Raftgo threads技巧raft实验易错点debug技巧 前记 趁着研一考完期末有点点空余…

软考29-上午题-【数据结构】-排序

一、排序的基本概念 1-1、稳定性 稳定性指的是相同的数据所在的位置经过排序后是否发生变化。若是排序后&#xff0c;次序不变&#xff0c;则是稳定的。 1-2、归位 每一趟排序能确定一个元素的最终位置。 1-3、内部排序 排序记录全部存放在内存中进行排序的过程。 1-4、外部…

微信小程序 --- wx.request网络请求封装

网络请求封装 网络请求模块难度较大&#xff0c;如果学习起来感觉吃力&#xff0c;可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API&#xff0c;如 wx.request()&#xff0c;wx.login() 等。这类 API 接口…

【精选】Java面向对象进阶——内部类

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

【操作系统】磁盘文件管理系统

实验六 磁盘文件管理的模拟实现 实验目的 文件系统是操作系统中用来存储和管理信息的机构&#xff0c;具有按名存取的功能&#xff0c;不仅能方便用户对信息的使用&#xff0c;也有效提高了信息的安全性。本实验模拟文件系统的目录结构&#xff0c;并在此基础上实现文件的各种…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…