Sortable 多列表相互拖拽

发布时间 2024-01-12 17:22:26作者: 吼吼酱

因为产品需求需要一个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:效果动图展示