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.pswp.cn/news/697021.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697021.shtml
英文地址,請注明出處:http://en.pswp.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;黃燈閃爍 使用數碼管顯示各自的倒計時時間。 按…

【CMake】(5)搜索文件

方法1:使用aux_source_directory命令 aux_source_directory命令用于查找指定目錄下的所有源文件,并將文件列表存儲到一個變量中。這種方法簡單易用,適合于源文件位于單一目錄下的情況。 基本語法如下: aux_source_directory(<dir> <variable>)<dir>:…

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負載均衡調度策…

Java高級 / 架構師 場景方案 面試題(二)

1.雙十一億級用戶日活統計如何用 Redis快速計算 在雙十一這種億級用戶日活統計的場景中&#xff0c;使用Redis進行快速計算的關鍵在于利用Redis的數據結構和原子操作來高效地統計和計算數據。以下是一個基于Redis的日活統計方案&#xff1a; 選擇合適的數據結構&#xff1a; …

核密度分析

一.算法介紹 核密度估計&#xff08;Kernel Density Estimation&#xff09;是一種用于估計數據分布的非參數統計方法。它可以用于多種目的和應用&#xff0c;包括&#xff1a; 數據可視化&#xff1a;核密度估計可以用來繪制平滑的密度曲線或熱力圖&#xff0c;從而直觀地表…

【DOCKER】隨手記

目錄 1. 安裝1.1 LINUX1.2 Windows 2. 常用配置2.1 普通權限運行2.2 開機自啟動2.3 3 更換Docker鏡像源2.4 更改默認存儲位置 3. 顯示帶UI的軟件4. 基于DOCKER的服務4.1 FTP4.2 Portainer4.3 Watchtower4.4 SiYuan4.5 GitLab4.5.1 創建容器4.5.2 克隆路徑問題4.5.3 獲取默認密碼…

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;但是不影響運行 打開工具欄下邊的菜單編輯器…

開窗Window和WindowAll的區別

在 Apache Flink 流處理框架中&#xff0c;窗口操作是處理流數據的重要部分。Flink 提供了時間窗口、計數窗口等多種窗口類型&#xff0c;用于將數據分割成不同的窗口進行聚合或其他處理。 Window 和 WindowAll 是 Flink 中窗口操作的兩種不同方式&#xff0c;它們分別對應不同…

GIT倉庫轉移--攜帶原分支及提交記錄

背景&#xff1a;最近公司倉庫位置需要移動&#xff0c;想保留原有的倉庫分支和提交記錄 操作&#xff1a; 目的位置新建倉庫&#xff08;要保證創建無誤&#xff09;原倉庫 git clone 到本地&#xff0c;git pull 保證代碼最新找到原倉庫.git/config 文件&#xff0c;修改 rem…

EPSON機器人與PC上位機軟件C#網絡TCP通訊

項目背景&#xff1a; 在非標設備PIN焊接機中用到了愛普生機器人。上位機軟件使用c#wpf開發。主要邏輯在上位機中。用愛普生機器人給焊接平臺實現自動上下料。 通訊方式&#xff1a;網絡TCP通訊&#xff0c;Socket 角色&#xff1a;上位機為服務端&#xff0c;機器人為客戶端…

Linux|centos7|錄屏神器asciinema的編譯安裝和離線化安裝使用

前言&#xff1a; asciinema這個錄屏軟件前面有一點研究&#xff0c;但它的部署安裝比較麻煩&#xff0c;雖然此軟件的安裝部署方式是很多的&#xff0c;比如yum安&#xff0c;apt&#xff0c;brew&#xff0c;docker&#xff0c;pip&#xff0c;rust編譯&#xff0c;docker等…

創建一個基于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;而不…

Java架構師之路七、大數據:Hadoop、Spark、Hive、HBase、Kafka等

目錄 Hadoop&#xff1a; Spark&#xff1a; Hive&#xff1a; HBase&#xff1a; Kafka&#xff1a; Java架構師之路六、高并發與性能優化&#xff1a;高并發編程、性能調優、線程池、NIO、Netty、高性能數據庫等。-CSDN博客Java架構師之路八、安全技術&#xff1a;Web安…

[前端]開啟VUE之路-NODE.js版本管理

VUE前端開發框架&#xff0c;以Node.js為底座。用歷史性的項目來學習&#xff0c;為了降低開發環境的影響因素&#xff0c;各種版本號最好能一致。前端項目也是一樣。為了項目能夠快速啟動&#xff0c;Node.js的版本管理&#xff0c;可以帶來很大的便利&#xff08;node.js快速…