Vue3 中使用 vuedraggable 实现拖拽排序功能,分组拖拽
安装draggable
npm install vuedraggable@next -- save
基础用法示例
< template>
< div class = "app-container" >
< draggable
v- model= "list"
item- key= "id"
: group= "{ name: 'items' }"
@end= "handleDragEnd"
>
< template #item= "{ element }" >
< div class = "item-card" >
< div class = "item-title" > { { element. name } } < / div>
< div class = "item-content" > { { element. description } } < / div>
< / div>
< / template>
< / draggable>
< / div>
< / template>
< script setup>
import { ref } from 'vue' ;
import draggable from 'vuedraggable' ;
const list = ref ( [
{ id: 1 , name: '项目1' , description: '描述1' } ,
{ id: 2 , name: '项目2' , description: '描述2' } ,
{ id: 3 , name: '项目3' , description: '描述3' }
] ) ;
const handleDragEnd = ( evt ) => {
const { newIndex, oldIndex } = evt;
console. log ( '从位置' + oldIndex + '移动到' + newIndex) ;
} ;
< / script>
< style scoped>
. item- card {
border: 1 px solid #dcdfe6;
border- radius: 4 px;
padding: 15 px;
margin- bottom: 10 px;
background: #fff;
cursor: move;
}
. item- title {
font- weight: bold;
margin- bottom: 8 px;
}
. item- content {
color: #666 ;
}
< / style>
重要属性说明
v-model
: 绑定数据源item-key
: 项目的唯一标识group
: 分组名称,相同组名的可以互相拖拽@end
: 拖拽结束事件@start
: 开始拖拽事件@change
: 顺序改变事件
分组拖拽
< template>
< div class = "group-container" >
< div v- for = "group in groups" : key= "group.id" class = "group" >
< h3> { { group. name } } < / h3>
< draggable
v- model= "group.items"
: group= "{ name: 'items' }"
item- key= "id"
@end= "(evt) => handleDragEnd(evt, group)"
>
< template #item= "{ element }" >
< div class = "item-card" >
{ { element. name } }
< / div>
< / template>
< / draggable>
< / div>
< / div>
< / template>
< script setup>
import { ref } from 'vue' ;
import draggable from 'vuedraggable' ;
const groups = ref ( [
{
id: 1 ,
name: '分组1' ,
items: [
{ id: 1 , name: '项目1' } ,
{ id: 2 , name: '项目2' }
]
} ,
{
id: 2 ,
name: '分组2' ,
items: [
{ id: 3 , name: '项目3' } ,
{ id: 4 , name: '项目4' }
]
}
] ) ;
const handleDragEnd = ( evt, group ) => {
const { newIndex, oldIndex } = evt;
console. log ( ` 在分组 ${ group. name} 中从位置 ${ oldIndex} 移动到 ${ newIndex} ` ) ;
} ;
< / script>
< style scoped>
. group- container {
display: flex;
gap: 20 px;
}
. group {
flex: 1 ;
padding: 15 px;
background: #f5f7fa;
border- radius: 4 px;
}
. item- card {
background: white;
padding: 10 px;
margin: 5 px 0 ;
border- radius: 4 px;
cursor: move;
}
< / style>
注意事项
确保每个拖拽项都有唯一的 key
使用 @end 事件而不是 @change 事件来处理排序结果
如果需要在拖拽时保存滚动位置,可以在 @start 事件中记录位置
组件卸载时注意清理相关事件监听
日常整理!