vue日历拖拽实现
Vue 日历拖拽实现方案
使用 vue-draggable 库
安装依赖库:
npm install vuedraggable
基础拖拽日历实现代码:
<template>
<div>
<draggable v-model="events" @end="onDragEnd">
<div v-for="event in events" :key="event.id" class="event-item">
{{ event.title }} - {{ event.date }}
</div>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: { draggable },
data() {
return {
events: [
{ id: 1, title: '会议', date: '2023-05-10' },
{ id: 2, title: '生日', date: '2023-05-15' }
]
}
},
methods: {
onDragEnd() {
// 拖拽结束后处理逻辑
}
}
}
</script>
结合 FullCalendar 实现专业拖拽
安装 FullCalendar 相关包:
npm install @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/vue
完整实现示例:
<template>
<FullCalendar
:options="calendarOptions"
@eventDrop="handleEventDrop"
/>
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default {
components: { FullCalendar },
data() {
return {
calendarOptions: {
plugins: [dayGridPlugin, interactionPlugin],
initialView: 'dayGridMonth',
editable: true,
events: [
{ title: '会议', start: '2023-05-10' },
{ title: '生日', start: '2023-05-15' }
]
}
}
},
methods: {
handleEventDrop(info) {
console.log('事件被拖拽到新日期:', info.event.start)
}
}
}
</script>
自定义拖拽实现方案
对于需要完全自定义的场景,可以使用原生拖拽API:
<template>
<div class="calendar">
<div
v-for="day in days"
:key="day.date"
class="day-cell"
@dragover.prevent
@drop="onDrop(day.date)"
>
<div
v-for="event in day.events"
:key="event.id"
draggable="true"
@dragstart="onDragStart(event)"
class="event"
>
{{ event.title }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
days: [
{ date: '2023-05-10', events: [...] },
{ date: '2023-05-11', events: [...] }
],
draggedEvent: null
}
},
methods: {
onDragStart(event) {
this.draggedEvent = event
},
onDrop(newDate) {
// 更新事件日期
this.draggedEvent.date = newDate
}
}
}
</script>
性能优化建议
对于大量日历事件的情况,考虑使用虚拟滚动技术。可以结合vue-virtual-scroller等库实现:
npm install vue-virtual-scroller
优化后的拖拽实现示例:
<template>
<RecycleScroller
:items="events"
:item-size="50"
class="scroller"
>
<template v-slot="{ item }">
<div
draggable="true"
@dragstart="onDragStart(item)"
class="event-item"
>
{{ item.title }}
</div>
</template>
</RecycleScroller>
</template>
移动端适配
针对移动设备添加触摸支持:
<template>
<div
v-for="event in events"
:key="event.id"
class="event"
@touchstart="touchStart(event)"
@touchmove="touchMove"
@touchend="touchEnd"
>
{{ event.title }}
</div>
</template>
<script>
export default {
methods: {
touchStart(event) {
this.touchStartY = event.touches[0].clientY
this.currentEvent = event
},
touchMove(e) {
const y = e.touches[0].clientY
const dy = y - this.touchStartY
// 实现拖动效果
},
touchEnd() {
// 处理拖动结束逻辑
}
}
}
</script>






