Sortable 多列表相互拖拽
因为产品需求需要一个table表头互相拖拽的例子,在对比了各种拖拽组件最后选择了Sortable。 下面是一个简版的例子,可以两个列表互相拖拽,也可以单个里面相互拖拽
1. 引入Sortable
访问地址: http://www.sortablejs.com/
yarn add sortablejs --S
2 html(用的是 vue3 编码)
<template> <div class="box"> <h2>拖拽调整展示状态及排序</h2> <div class="item"> <div>展示 {{ visibleList.length }}</div> <div class="flexDrap" id="visibleDrap"> <div v-for="item in visibleList" :key="item.code" class="visibleItem"> {{ item.name }} </div> </div> </div> <div class="item"> <div>不展示 {{ invisibleList.length }}</div> <div class="flexDrap" style="min-height: 80px" id="invisibleDrap"> <div v-for="item in invisibleList" :key="item.code" class="invisibleItem" > {{ item.name }} </div> </div> </div> </div> </template> <style> .box { background: white; width: 600px; padding: 16px; color: #333; } .item { background: #f5f8fe; border: 1px dashed #f2f2f2; padding: 10px 20px; margin-bottom: 16px; } .flexDrap { display: flex; flex-wrap: wrap; flex-direction: row; gap: 12px; } .visibleItem, .invisibleItem { background: blue; color: white; cursor: move; width: 110px; border-radius: 8px; text-align: center; height: 30px; line-height: 30px; } </style>
3. script
invisibleDrap 和 visibleDrap两个id 必须要设置
<script setup> import Sortable from "sortablejs"; const visibleList = ref([]); const invisibleList = ref([]); const list = ref([ { isShow: true, name: "繁花", code: "1" }, { isShow: true, name: "宝总", code: "2" }, { isShow: true, name: "汪小姐", code: "3" }, { isShow: true, name: "梅萍", code: "4" }, { isShow: true, name: "爷叔", code: "5" }, { isShow: true, name: "陶陶", code: "6" }, { isShow: true, name: "至真园", code: "7" }, { isShow: true, name: "李李", code: "8" }, { isShow: true, name: "夜东京", code: "9" }, { isShow: true, name: "玲子", code: "10" }, { isShow: true, name: "范总", code: "11" }, { isShow: true, name: "魏总", code: "12" }, { isShow: true, name: "金花", code: "13" }, { isShow: true, name: "葛老师", code: "14" }, { isShow: true, name: "A总", code: "15" }, { isShow: true, name: "小江西", code: "16" }, { isShow: true, name: "金美玲", code: "17" }, { isShow: true, name: "小阿嫂", code: "18" }, { isShow: true, name: "玲花", code: "19" }, ]); visibleList.value = [...list.value].filter((e) => e.isShow); invisibleList.value = [...list.value].filter((e) => !e.isShow); onMounted(() => { onDrop(); }); // 主要的拖拽方法 function onDrop() { new Sortable(visibleDrap, { animation: 150, handle: ".visibleItem", group: "shared", onEnd: function (evt) { console.log(evt.to.id); //获取拖动后的排序 if (evt.to.id === "invisibleDrap") { let itemToAdd = null; if (evt.oldIndex !== null) { itemToAdd = visibleList.value.splice(evt.oldIndex, 1)[0]; } if (evt.newIndex !== null && itemToAdd) { const itemNew = { ...itemToAdd, isShow: false }; //移动过后记得修改的值isShow invisibleList.value.splice(evt.newIndex, 0, itemNew); } } else { let itemToAdd = null; if (evt.oldIndex !== null) { itemToAdd = visibleList.value.splice(evt.oldIndex, 1)[0]; } if (evt.newIndex !== null && itemToAdd) { visibleList.value.splice(evt.newIndex, 0, itemToAdd); } } }, }); new Sortable(invisibleDrap, { animation: 150, handle: ".invisibleItem", group: "shared", onEnd: function (evt) { //获取拖动后的排序 if (evt.to.id === "visibleDrap") { let itemToAdd = null; if (evt.oldIndex !== null) { itemToAdd = invisibleList.value.splice(evt.oldIndex, 1)[0]; } if (evt.newIndex !== null && itemToAdd) { const itemNew = { ...itemToAdd, isShow: true }; //移动过后记得修改的值isShow visibleList.value.splice(evt.newIndex, 0, itemNew); } } else { let itemToAdd = null; if (evt.oldIndex !== null) { itemToAdd = invisibleList.value.splice(evt.oldIndex, 1)[0]; } if (evt.newIndex !== null && itemToAdd) { invisibleList.value.splice(evt.newIndex, 0, itemToAdd); } } }, }); } </script>
4:结果展示
5:效果动图展示
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端