強烈推薦一款好用到爆的可視化拖拽庫 VueDragablePlus

今天給大家推薦這款拖拽組件VueDraggablePlus,試了一下非常不錯,據說還被尤雨溪推薦過,咱們國人自己開發的,中國人不騙🇨🇳人,我就再來推薦一遍吧。

背後的故事

提到拖拽功能的實現,大家首先想到的幾乎都是大名鼎鼎的Sortablejs

和大家一樣,Sortablejs也是我開發時的首選, 由於項目使用的是 Vue3,選擇了Sortablejs官方封裝的 vue.draggable.next

但是在使用過程中發現很多問題,開發過程並不順利,其中一個問題和這個網友遇到的一樣,使用 socket.io 更新列表時,總是報這個錯誤:

找解決方案過程中,發現這個庫最近一次更新已經是 3 年前了:

看到 issue 回覆中,都在推薦VueDraggablePlus這個庫, 糾結再三還是放棄了Sortablejs官方封裝支持 vue 的庫。

關於 VueDraggablePlus

VueDraggablePlus 是一個專爲 Vue 打造的拖拽排序模塊,基於 Sortablejs 封裝,支持 Vue3 或 Vue 2.7+。之前,Vue 作者尤雨溪還在社交媒體上推薦了這款組件。

解決痛點

在 Sortablejs 官方以往的 Vue 組件中,都是通過使用組件作爲列表的直接子元素來實現拖拽列表,當我們使用一些組件庫時,如果組件庫中沒有提供列表根元素的插槽,我們很難實現拖拽列表,vue-draggable-plus 完美解決了這個問題,它可以讓你在任何元素上使用拖拽列表,我們可以使用指定元素的選擇器,來獲取到列表根元素,然後將列表根元素作爲 Sortablejs 的 container

技術特性

上面提到了,vue-draggable-plus提供三種方式:組件使用方式、hooks 使用方式和指令使用方式。下面都給大家介紹一下具體如何使用。

使用

安裝

首先安裝依賴

npm install vue-draggable-plus
// 或者
yarn add vue-draggable-plus

首先導入vue-draggable-plus組件:

import { VueDraggable } from 'vue-draggable-plus'

組件使用方式

<template>
    <div class="flex w-full">
      <VueDraggable
        ref="el"
        v-model="list"
        :animation="150"
        ghostClass="ghost"
        class="flex w-full flex-col gap-2 p-4 h-300px"
      >
        <div
          v-for="item in list"
          :key="item.id"
          class="cursor-move flex justify-between h-30"
        >
        <span>{{ item.id }}</span>
        <span>{{ item.name }}</span>
        </div>
      </VueDraggable>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref } from 'vue'
  import { type UseDraggableReturn, VueDraggable } from 'vue-draggable-plus'
  const list = ref([
    {
      name: '風險編號',
      id: "riskNumber"
    },
    {
      name: '風險點等級',
      id:  "rishLevel"
    },
    {
      name: '控制目標',
      id: "control target"
    },
    {
      name: '影響程度',
      id:  "degree of influnce"
    }
  ])
  const el = ref<UseDraggableReturn>()
  </script>
  
  <style scoped>
  .ghost {
    opacity: 0.5;
    background: #c8ebfb;
  }
  </style>

函數使用

多列表之間拖拽排序, 可以通過設置相同的group屬性來實現:

<template>
  <div class="flex gap-2 p-4 w-300px h-300px m-auto bg-gray-500/5 rounded">
    <section ref="el1" class="w-[50%]">
      <div
        v-for="item in list1"
        :key="item.id"
        class="flex justify-between h-30 bg-gray-500/5 rounded p-3 cursor-move"
      >
        <span>{{ item.name }}</span>
      </div>
    </section>
    <section ref="el2" class="w-[50%]">
      <div
        v-for="item in list2"
        :key="item.id"
        class="flex justify-between h-30 bg-gray-500/5 rounded p-3 cursor-move"
      >
        <span>{{ item.name }}</span>
      </div>
    </section>
  </div>
</template>
  
<script setup lang="ts">
import { ref } from "vue";
import { type UseDraggableReturn, VueDraggable } from "vue-draggable-plus";
import { useDraggable } from "vue-draggable-plus";

const list1 = ref([
  {
    name: "風險編號",
    id: "riskNumber",
  },
  {
    name: "風險點等級",
    id: "rishLevel",
  },
  {
    name: "控制目標",
    id: "control target",
  },
  {
    name: "影響程度",
    id: "degree of influnce",
  },
]);
const list2 = ref([
  {
    name: "曝光量",
    id: "open",
  },
  {
    name: "展示數",
    id: "show",
  },
  {
    name: "點擊數",
    id: "click",
  },
  {
    name: "轉化數",
    id: "buy",
  },
]);
const el1 = ref();
const el2 = ref();

useDraggable(el1, list1, {
  animation: 150,
  ghostClass: "ghost",
  group: "number",
});
useDraggable(el2, list2, {
  animation: 150,
  ghostClass: "ghost",
  group: "number",
});
</script>
  
<style scoped>
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
</style>

指令使用方式

我們可以將表格的 thead 指定爲目標容器,實現表格列拖拽

<template>
  <table class="table table-striped">
    <thead class="thead-dark">
      <tr v-draggable="headers">
        <th class="cursor-move" v-for="header in headers" :key="header.value">
          {{ header.text }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in list" :key="item.name">
        <td v-for="header in headers" :key="header">
          {{ item[header.value] }}
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { vDraggable } from "vue-draggable-plus";
const headers = ref([
  {
    text: "序號",
    value: "id",
  },
  {
    text: "日期",
    value: "date",
  },
  {
    text: "展示量",
    value: "show",
  },
]);
const list = ref([
  {
    date: "2023-10-10",
    show: 17800,
    id: 1,
  },
  {
    date: "2023-10-11",
    show: 56231,
    id: 2,
  },
  {
    date: "2023-10-12",
    show: 763230,
    id: 3,
  },
  {
    date: "2023-10-13",
    show: 21232,
    id: 4,
  },
]);
</script>
<style scoped>
tr {
  height: 48px;
  background: #fafafa;
  text-align: center;
}
tr td,
tr th {
  min-width: 60px;
}
tr:nth-child(2n) {
  background-color: #f1f6ff;
}
.table {
  width: 100%;
}
</style>

還有更多的使用方式,可以查看官方文檔:https://alfred-skyblue.github.io/vue-draggable-plus/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/-EnI8uK62kSBdK_Py9ToMw