背景
想要通过拖拽字段自动生成表格内容,实现数据实时分析的效果。
效果
安装
npm i -S vuedraggable || yarn add vuedraggable
引入
import draggable from "vuedraggable";
注册
components: {
draggable,
}
页面使用
<template>
<div id="app">
<div class="status">{{ drag ? "拖拽中" : "拖拽停止" }}</div>
<div class="container">
<div class="box">
<h3>数据字段</h3>
<draggable
v-model="box1Items"
item-key="id"
group="shared"
@start="onStart"
@end="onEnd"
>
<template v-slot:item="{ element }">
<div class="item">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="box">
<h3>已选择字段</h3>
<draggable
v-model="box2Items"
item-key="id"
group="shared"
@start="onStart"
@end="onEnd"
>
<template v-slot:item="{ element }">
<div class="item">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="box" style="width: 600px">
<table v-if="box2Items.length" class="transaction-table">
<thead>
<tr>
<th v-for="item in box2Items" :key="item.id">
{{ item.name }}
</th>
</tr>
</thead>
<tbody>
<tr>
<td v-for="item in box2Items" :key="item.id">
{{ formatCurrency(item.balance) }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
事件
<script>
import draggable from "vuedraggable";
export default {
components: {
draggable,
},
data() {
return {
drag: false,
//定义要被拖拽对象的数组
box1Items: [
{ id: 1, name: "客户 A", balance: 10000 },
{ id: 2, name: "客户 B", balance: 25000 },
{ id: 3, name: "客户 C", balance: 5000 },
{ id: 4, name: "客户 D", balance: 15000 },
{ id: 5, name: "客户 E", balance: 8000 },
{ id: 6, name: "客户 F", balance: 22000 },
{ id: 7, name: "客户 G", balance: 35000 },
{ id: 8, name: "客户 H", balance: 27000 },
],
box2Items: [],
};
},
methods: {
//开始拖拽事件
onStart() {
this.drag = true;
},
//拖拽结束事件
onEnd() {
this.drag = false;
},
formatCurrency(value) {
if (typeof value === "number" && !isNaN(value)) {
return `$${value.toFixed(2)}`;
}
return `$0.00`;
},
},
};
</script>
完整代码
<template>
<div id="app">
<div class="status">{{ drag ? "拖拽中" : "拖拽停止" }}</div>
<div class="container">
<div class="box">
<h3>数据字段</h3>
<draggable
v-model="box1Items"
item-key="id"
group="shared"
@start="onStart"
@end="onEnd"
>
<template v-slot:item="{ element }">
<div class="item">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="box">
<h3>已选择字段</h3>
<draggable
v-model="box2Items"
item-key="id"
group="shared"
@start="onStart"
@end="onEnd"
>
<template v-slot:item="{ element }">
<div class="item">
{{ element.name }}
</div>
</template>
</draggable>
</div>
<div class="box" style="width: 600px">
<table v-if="box2Items.length" class="transaction-table">
<thead>
<tr>
<th v-for="item in box2Items" :key="item.id">
{{ item.name }}
</th>
</tr>
</thead>
<tbody>
<tr>
<td v-for="item in box2Items" :key="item.id">
{{ formatCurrency(item.balance) }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
import draggable from "vuedraggable";
export default {
components: {
draggable,
},
data() {
return {
drag: false,
//定义要被拖拽对象的数组
box1Items: [
{ id: 1, name: "客户 A", balance: 10000 },
{ id: 2, name: "客户 B", balance: 25000 },
{ id: 3, name: "客户 C", balance: 5000 },
{ id: 4, name: "客户 D", balance: 15000 },
{ id: 5, name: "客户 E", balance: 8000 },
{ id: 6, name: "客户 F", balance: 22000 },
{ id: 7, name: "客户 G", balance: 35000 },
{ id: 8, name: "客户 H", balance: 27000 },
],
box2Items: [],
};
},
methods: {
//开始拖拽事件
onStart() {
this.drag = true;
},
//拖拽结束事件
onEnd() {
this.drag = false;
},
formatCurrency(value) {
if (typeof value === "number" && !isNaN(value)) {
return `$${value.toFixed(2)}`;
}
return `$0.00`;
},
},
};
</script>
<style scoped>
.status {
text-align: center;
margin-bottom: 20px;
font-size: 18px;
color: #333;
font-weight: bold;
}
.container {
display: flex;
justify-content: space-around;
gap: 20px;
}
.box {
width: 420px;
height: 600px;
padding: 15px;
background-color: #f4f4f4;
border: solid 2px #ccc;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow-y: auto;
}
.box h3 {
margin-bottom: 15px;
font-size: 20px;
color: #444;
font-weight: 600;
}
.item {
padding: 12px;
background-color: #ffffff;
border: solid 2px #ddd;
margin-bottom: 12px;
border-radius: 6px;
cursor: move;
transition: background-color 0.3s, border-color 0.3s;
}
.item:hover {
background-color: #f9f9f9;
border-color: #bbb;
}
.transaction-table {
margin-top: 20px;
width: 100%;
border-collapse: collapse;
}
.transaction-table th,
.transaction-table td {
padding: 10px;
border: 1px solid #ddd;
text-align: center;
}
.transaction-table th {
background-color: #f4f4f4;
font-weight: 600;
}
.transaction-table td {
background-color: #ffffff;
}
.transaction-table tr:nth-child(even) {
background-color: #f9f9f9;
}
</style>
官方地址:https://github.com/SortableJS/Vue.Draggable
中文版文档:vue.draggable中文文档 - itxst.com