vue实现拆分拖拽
Vue 实现拆分拖拽功能
拆分拖拽通常指将界面元素拆分为多个可拖拽的组件,并允许用户自由组合。以下是基于 Vue 的实现方法:
使用 Vue.Draggable 库
安装依赖:
npm install vuedraggable
基础示例代码:
<template>
<div>
<draggable v-model="list" group="components" @end="onDragEnd">
<div v-for="element in list" :key="element.id">
{{ element.name }}
</div>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
list: [
{ id: 1, name: '组件A' },
{ id: 2, name: '组件B' }
]
}
},
methods: {
onDragEnd() {
console.log('拖拽完成')
}
}
}
</script>
实现多区域拖拽
创建多个拖拽区域并允许元素在区域间移动:
<template>
<div class="container">
<div class="area">
<h3>区域1</h3>
<draggable v-model="area1" group="components">
<div v-for="item in area1" :key="item.id">
{{ item.name }}
</div>
</draggable>
</div>
<div class="area">
<h3>区域2</h3>
<draggable v-model="area2" group="components">
<div v-for="item in area2" :key="item.id">
{{ item.name }}
</div>
</draggable>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
area1: [
{ id: 1, name: '组件A' },
{ id: 2, name: '组件B' }
],
area2: [
{ id: 3, name: '组件C' }
]
}
}
}
</script>
<style>
.container {
display: flex;
}
.area {
width: 200px;
margin: 10px;
padding: 10px;
border: 1px solid #ddd;
}
</style>
自定义拖拽手柄
添加拖拽手柄而非整个元素可拖拽:
<template>
<draggable v-model="list" handle=".handle">
<div v-for="item in list" :key="item.id">
<span class="handle">≡</span>
{{ item.name }}
</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
list: [
{ id: 1, name: '组件A' },
{ id: 2, name: '组件B' }
]
}
}
}
</script>
<style>
.handle {
cursor: move;
margin-right: 10px;
}
</style>
实现嵌套拖拽
支持嵌套结构的拖拽功能:
<template>
<draggable
v-model="treeData"
group="nested"
@change="log"
item-key="id">
<template #item="{element}">
<div>
{{ element.name }}
<nested-draggable
v-if="element.children"
:items="element.children" />
</div>
</template>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable,
'nested-draggable': {
template: `
<draggable
v-model="internalItems"
group="nested"
item-key="id">
<template #item="{element}">
<div style="margin-left:20px">
{{ element.name }}
<nested-draggable
v-if="element.children"
:items="element.children" />
</div>
</template>
</draggable>`,
components: { draggable },
props: ['items'],
computed: {
internalItems: {
get() { return this.items },
set(value) { this.$emit('update:items', value) }
}
}
}
},
data() {
return {
treeData: [
{
id: 1,
name: '父节点',
children: [
{ id: 2, name: '子节点1' },
{ id: 3, name: '子节点2' }
]
}
]
}
},
methods: {
log(evt) {
console.log(evt)
}
}
}
</script>
实现拖拽排序与克隆
允许元素克隆而非移动:
<template>
<div>
<h3>源列表</h3>
<draggable
v-model="source"
:group="{ name: 'components', pull: 'clone', put: false }"
item-key="id">
<div v-for="item in source" :key="item.id">
{{ item.name }}
</div>
</draggable>
<h3>目标列表</h3>
<draggable
v-model="target"
group="components"
item-key="id">
<div v-for="item in target" :key="item.id">
{{ item.name }}
</div>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
source: [
{ id: 1, name: '组件A' },
{ id: 2, name: '组件B' }
],
target: []
}
}
}
</script>
注意事项
- 确保为每个拖拽元素设置唯一的key值
- 复杂场景建议使用Vuex管理状态
- 移动端需要额外处理touch事件
- 性能优化:大数据量使用虚拟滚动
以上方法可根据实际需求组合使用,实现各种复杂的拆分拖拽场景。







