Vue組件設(shè)計之多列表拖拽交換排序功能實現(xiàn)
在前端開發(fā)中,拖拽排序是一種提升用戶體驗非常好的方式,常見的場景有單列表拖拽排序,多列表拖拽交換排序,比如以下這種效果:
下面將以這種效果為例,設(shè)計一個組件。
1. 安裝所需依賴
npm install vuedraggable --save
本例中目前所用的版本為:2.20.0
2. 組件設(shè)計實現(xiàn)
<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>
到此這篇關(guān)于Vue組件設(shè)計之多列表拖拽交換排序的文章就介紹到這了,更多相關(guān)vue拖拽交換排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.js@2.6.10更新內(nèi)置錯誤處機制Fundebug同步支持相應(yīng)錯誤監(jiān)控
這篇文章主要介紹了Vue.js@2.6.10更新內(nèi)置錯誤處機制,F(xiàn)undebug同步支持相應(yīng)錯誤監(jiān)控 ,需要的朋友可以參考下2019-05-05vue中使用element-ui進(jìn)行表單驗證的實例代碼
這篇文章主要介紹了vue中使用element-ui進(jìn)行表單驗證的實例代碼,本文給大家分享實現(xiàn)思路,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06vue自定義標(biāo)簽和單頁面多路由的實現(xiàn)代碼
這篇文章主要介紹了vue自定義標(biāo)簽和單頁面多路由的實現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05vue3.0父子傳參,子修改父數(shù)據(jù)的實現(xiàn)
這篇文章主要介紹了vue3.0父子傳參,子修改父數(shù)據(jù)的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04vue日常開發(fā)基礎(chǔ)Axios網(wǎng)絡(luò)庫封裝
這篇文章主要為大家介紹了vue日常開發(fā)基礎(chǔ)Axios網(wǎng)絡(luò)庫封裝示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Vue中實現(xiàn)父子組件雙向數(shù)據(jù)流的三種方案分享
通常情況下,父子組件的通信都是單向的,或父組件使用props向子組件傳遞數(shù)據(jù),或子組件使用emit函數(shù)向父組件傳遞數(shù)據(jù),本文將嘗試講解Vue中常用的幾種雙向數(shù)據(jù)流的使用,需要的朋友可以參考下2023-08-08