vue2 element el-transfer穿梭框組件支持拖拽及排序 已封裝,隨取隨用

項目場景:

項目中有個功能用到穿梭框組件,新版本需要支持穿梭框組件排序,由于element2版本中的穿梭框組件本身不支持排序功能

在此不僅需要支持隨意更換順序,還支持從一側拖拽至另一側,具體功能效果圖如下:
在這里插入圖片描述
啊啊啊對不住哈哈,GIF過于模糊,自行腦補吧,臨時沒找到免費的視頻轉GIF


穿梭框組件封裝代碼如下

提示:關于拖拽部分代碼是基于其他大佬的基礎上稍作修改,原博文地址:[https://blog.csdn.net/juvenile_Li/article/details/126886010?spm=1001.2014.3001.5506]

Tips1: 此功能使用到了sortablejs插件,請務必先下載本插件再引用下面的代碼,sortablejs安裝命令為:npm install sortablejs --save

Tips2: 下面的代碼中引入的其他方法請自行根據自己的項目進行修改,比如:錯誤提示Messagebox

//先看封裝好的組件,此處我們是加了彈框的,如果不需要自行修改去掉即可
<template><div class="delete-info-dialog"><el-dialog:title="dialogTitle":visible.sync="tableItemDialogVisible":close-on-click-modal="false":close-on-press-escape="false"width="700px":before-close="handleClose"><div class="info-body"><el-transfer ref="transfer"v-model="visibleValue":data="transferData":titles="transferTitle"target-order="push":props="transferProps"@left-check-change="leftCheckChange"@right-check-change="rightCheckChange"><span slot-scope="{ option }"draggable="!option.disabled"@dragstart="drag($event, option)">{{ option.label }}</span></el-transfer></div><span slot="footer" class="dialog-footer"><el-button type="primary" @click="handleConfirm">確 定</el-button></span></el-dialog></div>
</template><script>
import Sortable from 'sortablejs' //記得安裝拖拽組件哦
import cloneDeep from "lodash.clonedeep"; //這個是深拷貝方法,也可以換成自己的,也可以下載lodash,此處為了避免修改父組件傳過來的數據
export default {name: "visible-item-table-dialog",props: {//此處是可以隨意定義彈框的文字,且有默認值dialogTitle: {type: String,default: '顯示列設置'},//此處是可以定義transfer組件的propstransferProps: {type: Object,default: {key: 'key',label: 'label',}},//此處是可以定義transfer組件的titletransferTitle: {type: Array,default: ()=> ['隱藏列', '顯示列']},// 穿梭框總數據transferDataList: {type: Array,default: ()=> []},// 右側顯示列,用戶已經選好保存過的數據,從父組件傳過來回顯visibleTableItemList: {type: Array,default: ()=> []},// 默認顯示列,如果用戶還沒設置過則取這個defaultTableItemList: {type: Array,default: ()=> []},// 控制彈框顯隱tableItemDialogVisible: {type: Boolean,default: false},},data() {return {visibleValue: [],//顯示列表頭數據transferData: [], // 穿梭框數據transferLeftCheckData: [], // 左側選中數據transferRightCheckData: [], // 右側選中數據draggingKey: '',  // 當前拖拽項}},mounted() {this.transferData = this.transferDataList;this.visibleValue = this.visibleTableItemList.length>0 ?cloneDeep(this.visibleTableItemList) : cloneDeep(this.defaultTableItemList);// 此處加nextTick 為了保證順利取到refsthis.$nextTick(()=>{const transfer = this.$refs.transfer.$el;const leftPanel = transfer.getElementsByClassName('el-transfer-panel')[0].getElementsByClassName('el-transfer-panel__body')[0]const rightPanel = transfer.getElementsByClassName('el-transfer-panel')[1].getElementsByClassName('el-transfer-panel__body')[0]const rightEl = rightPanel.getElementsByClassName('el-transfer-panel__list')[0]Sortable.create(rightEl, {onEnd: evt => {const { oldIndex, newIndex } = evtconst temp = this.visibleValue[oldIndex]if (!temp || temp === 'undefined') {return} // 解決右邊最后一項從右邊拖左邊,有undefined的問題// this.$set(this.visibleValue, oldIndex, this.visibleValue[newIndex]) //這種賦值方法會導致數據更新視圖未更新,排序后順序展示錯亂,強制更新也無效,原博主是這么賦值的,僅供參考// this.$set(this.visibleValue, newIndex, temp)let _arr = this.visibleValue.splice(oldIndex, 1)this.visibleValue.splice(newIndex, 0, _arr[0])}})// 目前只讓右側支持拖拽順序即可,左側暫時注釋const leftEl = leftPanel.getElementsByClassName('el-transfer-panel__list')[0]Sortable.create(leftEl, {onEnd: evt => {const { oldIndex, newIndex } = evtconst temp = this.transferData[oldIndex]if (!temp || temp === 'undefined') {return} // 解決右邊最后一項從左邊拖右邊,有undefined的問題            let _arr = this.transferData.splice(oldIndex, 1)this.transferData.splice(newIndex, 0, _arr[0])}})// 關于左側拖拽至右側的功能,在本項目中暫時無法實現,經檢測drag事件未觸發(除了本項目外都可),后續再研究^_^leftPanel.ondragover = ev => ev.preventDefault()leftPanel.ondrop = ev => {ev.preventDefault()// 往左拉const index = this.visibleValue.indexOf(this.draggingKey)if (index !== -1) {// 如果當前拉取的是選中數據就將所有選中的數據拉到左邊選中框內if (this.transferRightCheckData.indexOf(this.draggingKey) !== -1) {// 此處為多選執行this.transferRightCheckData.reduce((arr, item) => {if (arr.indexOf(item) !== -1) {// 每次計算將相同的刪掉arr.splice(arr.indexOf(item), 1)}return arr}, this.visibleValue)this.transferRightCheckData = []// 清除右側選中的 不然下次向左拉取時會有緩存// 否則就只拉取當前一個} else {this.visibleValue.splice(index, 1)}}}rightPanel.ondragover = ev => ev.preventDefault()rightPanel.ondrop = ev => {ev.preventDefault()if (!this.draggingKey || this.draggingKey === 'undefined') {return} // 解決右邊最后一項從左邊拖右邊,有undefined的問題// 右邊框里沒有當前key值的時候 向右拉if (this.visibleValue.indexOf(this.draggingKey) === -1) {// 此處為多選執行// 如果當前拉取的是選中數據就將所有選中的數據拉到右邊選中框內if (this.transferLeftCheckData.indexOf(this.draggingKey) !== -1) {this.visibleValue =this.visibleValue.concat(this.transferLeftCheckData)this.transferLeftCheckData = [] // 清除左側選中的  不然下次向右拉取時會有緩存} else {// 否則就只拉取當前一個this.visibleValue.push(this.draggingKey)}}}})},methods: {//關閉彈框handleClose(){this.$emit("handleCloseTableItem");},//點擊確定按鈕handleConfirm(){if(this.visibleValue.length<=0){this.$message({message: '未選中任何需要顯示的數據',type: 'warning'});return;}this.$emit("handleConfirmVisible",this.visibleValue)},drag(ev, option) {// 賦值當前拖拽的唯一標識this.draggingKey = option[this.transferProps.key]},leftCheckChange(val) {// 穿梭框左側多選選中this.transferLeftCheckData = [...val]},rightCheckChange(val) {// 穿梭框右側多選選中this.transferRightCheckData = [...val]},},
}
</script><style lang="scss" scoped>
.delete-info-dialog{/deep/ .el-dialog__body{max-height: 400px;overflow-y: auto;}.info-body{color: #909399;padding-top: 20px;padding-bottom: 20px;.success-info{height: 20px;line-height: 20px;}.info-list{.info{padding: 0 10px;line-height: 20px;word-break: break-all;}}}
}
</style>

封裝組件的應用:

提示:上面的代碼是封裝好的支持拖拽的穿梭框,且在彈框內哦,不在彈框內的自己修改下吧O(∩_∩)O哈哈~:

第一步:在需要的頁面引入封裝好的組件
//此處用Button觸發彈框打開,不需要彈框的省略
<el-button @click="tableItemDialogVisible= true">打開封裝好的穿梭框組件彈框</el-button><visible-dialog:default-table-item-list="defaultTableItemList":table-item-dialog-visible="tableItemDialogVisible"v-if="tableItemDialogVisible":visible-table-item-list="visibleTableItemList":transfer-data-list="transferDataList":transfer-props="{key: 'property',label: 'label',}"@handleCloseTableItem="handleCloseTableItem"@handleConfirmVisible="handleConfirmVisible"></visible-dialog><script>
import VisibleDialog from "../../../components/visible-dialog/index.vue"; //記得修改地址哦,這里引入的就是上面那個封裝好的組件,地址務必改為自己的哈,文件名也記得改為自己的哈
export default {   components: {VisibleDialog },data(){return {               tableItemDialogVisible: true,//顯隱彈框defaultTableItemList: ['date', 'invoiceClass', 'invoiceCode', 'invoiceNum', 'isTravel'],//如果visibleTableItemList為空,直接取defaultTableItemList的值,這個邏輯可根據自己需要自行修改transferDataList: [{label: '銷售方名稱', property: 'salename', align:'left', minWidth: 180},{label: '銷售方稅號', property: 'saleaxpayerid', align:'left', minWidth: 180},{label: '購買方稅號', property: 'buytaxnumber', align:'left', minWidth: 180},{label: '發票日期', property: 'date', minWidth: 120,},{label: '發票類型', property: 'invoiceClass', minWidth: 180,},{label: '發票代碼', property: 'invoiceCode', minWidth: 180,},{label: '發票號碼', property: 'invoiceNum', minWidth: 180,},{label: '是否差旅', property: 'isTravel', minWidth: 120},],visibleTableItemList: [],//這個數組的數據是從后來請求回來的,用戶自己設置好順序的數據,如果沒有設置就會去取defaultTableItemList里面的數據,這個demo中咱們就默認為空,假裝用戶還沒設置過哈}},methods: {//  關閉顯示列彈框handleCloseTableItem(){this.tableItemDialogVisible = false;},// 點擊彈框的確認按鈕事件,array就是用戶自己放在右側排好序的數組,handleConfirmVisible(array){console.log("用戶選擇好的右側的數據",array)// 這里就可以向后端發送請求,保存用戶排好序的數據了},}}
</script>

結語:

提示:按照上述代碼復制到自己項目中即可實現頂部GIF中的功能了,如有問題,歡迎留言交流,歡迎大佬指點。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164045.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164045.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

為什么JSX只能在函數的返回語句中使用

JSX只能在函數的返回語句中使用&#xff0c;因為JSX本質上是一種聲明式的語法&#xff0c;用于描述React組件的結構和外觀。在函數的返回語句中使用JSX&#xff0c;可以將JSX表達式嵌入到組件的輸出中。 當我們編寫一個React組件時&#xff0c;我們通常需要定義一個Render函數…

消息中間件——RabbitMQ(五)快速入門生產者與消費者,SpringBoot整合RabbitMQ!

前言 本章我們來一次快速入門RabbitMQ——生產者與消費者。需要構建一個生產端與消費端的模型。什么意思呢&#xff1f;我們的生產者發送一條消息&#xff0c;投遞到RabbitMQ集群也就是Broker。 我們的消費端進行監聽RabbitMQ&#xff0c;當發現隊列中有消息后&#xff0c;就進…

森利威爾SL4010 升壓恒壓 12V升壓24V 12V升壓36V 12V升壓48V

在當今的電子設備中&#xff0c;電源管理系統的設計是非常重要的。為了保證設備的穩定運行&#xff0c;升壓和恒壓電源的應用已經成為不可或缺的一部分。在這篇文章中&#xff0c;我們將介紹森利威爾SL4010升壓恒壓電源&#xff0c;它可以實現12V升壓24V、12V升壓36V、12V升壓4…

c 在文本終端中顯示yuv圖片

把yuv422 轉為rgb32 &#xff0c;利用framebuffer 顯示 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <lin…

vue2.6源碼分析

vue相關文檔 vue-cli官方文檔 vuex官方文檔 vue-router 官方文檔 vue2.6源碼地址 如何調試源碼 package.json 添加了--sourcemap "scripts": {"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev --sourcemap" }新增…

linux apt update錯誤提示修復

錯誤提示&#xff1a; E: Release file for http://security.debian.org/dists/bullseye-security/InRelease is expired (invalid since 15d 14h 45min 26s). Updates for this repository will not be applied. E: Release file for http://ftp.jp.debian.org/debian/dists/b…

【Hello Go】Go語言并發編程

并發編程 概述基本概念go語言的并發優勢 goroutinegoroutine是什么創建goroutine如果主goroutine退出runtime包GoschedGoexitGOMAXPROCS channel無緩沖的channel有緩沖的channelrange和close單向channel 定時器TimerTicker Select超時 概述 基本概念 并行和并發概念 并行 &…

CVE-2023-6099:優卡特臉愛云一臉通智慧管理平臺SystemMng.ashx接口未授權漏洞復現

文章目錄 優卡特臉愛云一臉通智慧管理平臺未授權SystemMng.ashx接口漏洞復現&#xff08;CVE-2023-6099&#xff09; [附POC]0x01 前言0x02 漏洞描述0x03 影響版本0x04 漏洞環境0x05 漏洞復現1.訪問漏洞環境2.構造POC3.復現 0x06 修復建議 優卡特臉愛云一臉通智慧管理平臺未授權…

mysql字符串轉為數字的三種方法、字符串轉日期

隱式轉換 在MySQL中&#xff0c;使用0運算符可以將一個非數字的值隱式地轉換為數字。這在進行數學運算或比較操作時非常有用。 需要注意的是&#xff0c;在使用0進行隱式轉換時&#xff0c;MySQL會盡可能將字符串轉換為數字。如果字符串不能轉換為數字&#xff0c;則會返回0。…

【解決】HDFS JournalNode啟動慢問題排查

文章目錄 一. 問題描述二. 問題分析1. 排查機器性能2. DNS的問題 三. 問題解決 一句話&#xff1a;因為dns的問題導致journalnode啟動時很慢&#xff0c;通過修復dns對0.0.0.0域名解析&#xff0c;修復此問題。 一. 問題描述 從journalnode啟動到服務可用&#xff0c;完成RPC…

使用Python將圖片轉換為PDF

將圖片轉為 PDF 的主要原因之一是為了方便共享和傳輸。此外&#xff0c;將多張圖片合并成一個 PDF 文件還可以簡化文件管理。之前文章詳細介紹過如何使用第三方庫Spire.PDF for Python將PDF文件轉為圖片&#xff0c;那么本文介紹使用同樣工具在Python中實現圖片轉PDF文件的功能…

【OpenCV+OCR】計算機視覺:識別圖像驗證碼中指定顏色文字

文章目錄 1. 寫在前面2. 讀取驗證碼圖像3. 生成顏色掩碼4. 生成黑白結果圖5. OCR文字識別6. 測試結果 【作者主頁】&#xff1a;吳秋霖 【作者介紹】&#xff1a;Python領域優質創作者、阿里云博客專家、華為云享專家。長期致力于Python與爬蟲領域研究與開發工作&#xff01; 【…

Spring Security(安全框架,必須登錄成功才能訪問指定資源)

一、背景知識 1、Spring Security 是一個能夠為基于Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean&#xff0c;充分利用了Spring IoC&#xff0c;DI&#xff08;IOC: 控制反轉Inversion of Control ,DI:D…

24路電磁鎖控板的特點和主要參數

智能快遞柜、智能生鮮柜、電子存儲柜、超市寄存柜、智能送餐柜、電子更衣柜、檔案柜等物聯網終端設備&#xff0c;都是采用電磁鎖控制&#xff0c;這種電磁鎖控制板俗稱鎖控板。鎖控板可以遠程控制儲物柜的開關以及遠程監控并提供鎖的反饋信號。沐渥開發的24路電磁鎖控板可以控…

AI:87-基于深度學習的街景圖像地理位置識別

?? 本文選自專欄:人工智能領域200例教程專欄 從基礎到實踐,深入學習。無論你是初學者還是經驗豐富的老手,對于本專欄案例和項目實踐都有參考學習意義。 ??? 每一個案例都附帶有在本地跑過的代碼,詳細講解供大家學習,希望可以幫到大家。歡迎訂閱支持,正在不斷更新中,…

OpenAI 曾收到 AI 重大突破警告;半獨立的 OpenAI 比與微軟合并更好丨 RTE 開發者日報 Vol.91

開發者朋友們大家好&#xff1a; 這里是 「RTE 開發者日報」 &#xff0c;每天和大家一起看新聞、聊八卦。我們的社區編輯團隊會整理分享 RTE &#xff08;Real Time Engagement&#xff09; 領域內「有話題的 新聞 」、「有態度的 觀點 」、「有意思的 數據 」、「有思考的 文…

ubuntu下docker環境使用GPU配置

本文主要講述整個命令流程&#xff0c;具體講解請看官網nvidia-容器工具包和一篇總結得很詳細的博文docker使用GPU總結 docker的版本必須安裝19.0版本以上的&#xff0c;這里也只講19.0版本以上的使用方法 首先設置一下網絡信息 curl -fsSL https://nvidia.github.io/libnvi…

LeetCode131. Palindrome Partitioning

文章目錄 一、題目二、題解 一、題目 Given a string s, partition s such that every substring of the partition is a palindrome . Return all possible palindrome partitioning of s. Example 1: Input: s “aab” Output: [[“a”,“a”,“b”],[“aa”,“b”]] Exa…

工具【1、計算時間差2、獲取當天時間前后七天時間3、根據當前數據的位置,在數組中插入數據4、數組中,某個屬性相同的數據放在一塊,如把某個日期相同的相連一起】

生成UUID /*** 唯一的隨機字符串&#xff0c;用來區分每條數據* returns {string}*/ export function getUid() {return xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g, (c) > {const r (Math.random() * 16) | 0;const v c x ? r : (r & 0x3) | 0x8;retu…

【圖文詳解】SiamFC++與圖注意力的強強聯合:單目標追蹤系統

1.研究背景與意義 隨著計算機視覺技術的不斷發展&#xff0c;單目標追蹤&#xff08;Single Object Tracking, SOT&#xff09;作為計算機視覺領域的一個重要研究方向&#xff0c;已經在許多實際應用中得到了廣泛的應用。單目標追蹤系統可以通過分析視頻序列中的目標運動&…