強烈推薦一款好用到爆的可視化拖拽庫 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
,
技術特性
-
功能強大:全面繼承
Sortable.js
拖拽排序庫的所有功能; -
Vue 生態支持好:兼容 Vue3 和 Vue2;
-
實用靈活:支持組件、指令、函數式調用,我們喜歡那種編程方式都沒問題;
-
TS 支持:這個庫本身就是用
TypeScript
編寫,有完整的 TS 文檔; -
數據綁定:支持
v-model
雙向綁定,不需要單獨維護排序數據; -
支持自定義容器:可以自定某個容器作爲拖拽容器,比
Sortable.js
更靈活。
上面提到了,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