夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 任务管理日历

    • 前言
    • 前端搭建

      • 前端指南
      • 项目初始化
      • 封装日历组件
      • 实现拖拽
        • vue3-dnd
        • useDrag
          • Forward、Event、Backward 拖动源
          • 拖动的事件处理
          • New 拖动源
          • Day 拖动源
        • useDrap
          • Day 放置源
          • 放置过程中的事件处理
        • 获取当月的所有事项
        • 将事项派发到每一天
        • 事项分类
          • 单天事项
          • 跨天事项
          • hasLast 和 hasNext 标识的作用
        • 事项的渲染位置
      • 实现弹窗
    • 后端搭建

    • 部署前置篇
    • 前端部署

    • 后端部署

  • 无代码平台

  • 图书管理系统

  • 《全栈项目》
  • 任务管理日历
  • 前端搭建
夜猫子
2023-03-15
目录

实现拖拽

# 实现拖拽

拖拽是该项目实现的关键,在这里我们使用的拖拽库是 vue3-dnd。

# vue3-dnd

vue3-dnd是基于 react-dnd开发的 ,它们两个语法 API 几乎一致,用过 react-dnd 的同学使用 vue3-dnd 几乎是无缝衔接。

后面的内容不会介绍 vue3-dnd 具体 API 的使用,只会介绍 vue3-dnd 在项目中的应用;

对 vue-dnd 或者 react-dnd 不熟悉的同学建议先查阅此文档 示例 (opens new window),否则后面的内容会有点晦涩难懂;

具体的业务实现代码,就不在这写了,没有多大意义,下面只分享一下实现思路;

# useDrag

useDrag函数提供了一种将你的组件作为拖拽源连接到 DnD 的方法。

# Forward、Event、Backward 拖动源

下面是一个 event 事项在页面中的 DOM 结构,可以看到,class 为 forward、content、backward 的 section 都具有拖拽属性 draggable;imgimg

forward:将事项向左拖拽进行跨天,比如将 12号 单天的事项变为 11号 至 12号 两天的连贯事项

content:事项本身的拖拽(组件名称为 Event)

backward:将事项向右拖拽进行跨天,比如将 12号 单天的事项变为 12号 至 13号 两天的连贯事项

# 拖动的事件处理

这三个拖动源在拖动结束时去更改一个当前事项的 startTime 和 endTime。

# New 拖动源

当前日期中无事项时,可以通过拖拽空白处,创建新的事项。 image.png

# Day 拖动源

Day 组件很特殊,因为它本身即是拖动源又是放置目标。 image.png

当其作为拖动源时,功能和 New 拖动源功能一致。

# useDrap

useDrop函数提供了一种将你的组件作为放置目标连接到 DnD 的方法。

# Day 放置源

Day 放置源会接受来自其他拖动源的信息。 image.png

Day 放置源暴露了两个属性,其可以使拖拽源在拖拽结束(end方法)时被获取。

  • fullTime:放置源的日期。

  • dateIndex:放置源在当前日期面板中的索引。

drop: () => ({
  // drag 侧可以通过 monitor.getDropResult() 拿到该值
  dropTime: props.dateInfo.fullTime,
  dateIndex: props.dateInfo.dateIndex,
}),
1
2
3
4
5

# 放置过程中的事件处理

当有拖拽组件经过时,该组件就会触发 hover 事件,并改变样式。

# 事件的渲染

# 获取当月的所有事项

单个事件的携带信息:

字段 描述
startTime 事项的开始时间
endTime 事项的结束时间
isDone 事项是否已完成
priority 事项的重要程度
title 事项标题
description 事项的描述信息

# 将事项派发到每一天

获取到当月所有的事项后,通过 getRenderEventList 函数与当月的日历进行处理后返回一个 renderList 列表。

watchEffect(async () => {
  const { renderList } = getRenderEventList(
    calendarInfo.value,
    eventList.value
  );
  renderEventList.value = renderList;
});
1
2
3
4
5
6
7

经过处理后返回的是一个长度为 42 的二维数组,一个数组代表一天的数据,而在这个数组内又有内层数组,内层数组中存放着每一个具体的事项。 image.png

# 事项分类

经过处理后的 renderList 中,事项可以分为两大类,当天事项和跨天事项。

# 单天事项

如果 startTime 和 endTime 是同一天,那么代表该事项只在当天展示; image.png

# 跨天事项

如果 startTime 和 endTime 不一样,那么代表该事项是跨天事项。 image.png

# hasLast 和 hasNext 标识的作用

hasLast 和 hasNext 的 标识符控制着 Forward 组件和 Backward 组件是否展示,我们在上文提到过,Forward 组件 和 Backward 组件都是拖动源,它的存在与否其实就代表着这个事项是否可以进行跨天拖拽。

我们以 12号这天的事项举例

如果 hasLast 为 false,那么渲染 Forward 组件,事项可以向左进行跨天拖拽

如果 hasNext 为 true,那么不渲染 Backward 组件,同时,事项还需要将右侧的留白位置进行样式填充

imgimg

# 事项的渲染位置

在经过数据处理后,有一个字段 _index,这个字段帮助我们定位渲染的初始位置。

我们以 11号 标题为 “举个例子” 这个事项为例,在 11号这天,它的渲染位置是第 2 个,那么如何保证后面的 12 号 至 15号,它的渲染位置一直是第 2 个呢?通过 _index 字段确认。 img

接收的参数:

dateIndex:日历每天的日期索引,0 开始,41结束,总共 42 天

lastEventList:日历中每天的 hasNext 属性为 true 的事项

eventAllList:当天的需要展示的所有事项

实现思路:

1.根据 dateIndex 获取前一天的所有 hasNext 属性的事项,并赋值给变量 lastEvents。

2.声明 showEventList ,存放当天最终需要渲染的事项。

3.将 lastEvents 和 当天的所有的事项根据 eventId 进行对比: a.如果 eventId 相等,那么代表该事项是跨天事项(因为前一天和当天的事项列表中都存在该事项)。 b.将前一天的 _index 赋值给当天的 _index,由此便确认了位置信息。 c.通过 showEventList[_index] 进行保存。

4.处理当天和以当天为开始日期的跨天事项,并赋值 _index。

5.在后续的展示过程中,就可以通过 _index 进行排序,由此确认事项的渲染位置 image.pngimage.png

编辑 (opens new window)
上次更新: 2024/6/18 13:14:59
封装日历组件
实现弹窗

← 封装日历组件 实现弹窗→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式