《Vue3+Typescript》一个简单的日历组件实现

这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言~博主看到后会去代替大家踩坑的~

主页: oliver尹的主页

格言: 跌倒了爬起来就好~

目录

一、前言

二、效果图

三、核心思路

四、代码实现

4.1 本月日期计算

4.2 上月日期补齐

4.3 下个月日期补齐

4.4 转化成二位数组

4.5 使用v-for生成日历

4.6 农历,假期等

五、小结


一、前言

近来项目中需要用到一个日历组件,由于找了找没有找到合适的,因此决定自己简单动手做一个,项目中肯定比这个复杂的多,这里只是给各个小伙伴一个思路或者说是开发的方向~

耐心看完,也许有所收获......(PS:如果要源码留下邮箱,博主看到后会发送的~)

二、效果图

大致效果图如下:

三、核心思路

日历的核心个人觉得就是 算出指定月份的第一天是星期几,为什么?因为,从形态上来说 日历展现出来就是这么一个7*6的矩形,如果知道1号是星期几,那么就可以把这个矩形在1号之前的日期补齐,最后一天后的日期也可以补齐;

因此,日历的计算一共可以分为三段:

  • 第一段,本月计算,计算的是当前1号是周几,接着计算本月一共多少天;
  • 第二段,上月计算,计算1号之前一共有几天;
  • 第三段,下月计算,计算的是本月之后一共有多少天;

这样,三段连在一起就是一组完整的当前数组,如果还不清楚,那再具体举一个例子吧,以2023年7月为例,7月的1号是周六,那么它应该在矩形的这个位置

那么在周六前面应该还有6天,需要取6月的最后6天来补齐这个矩形的前半段

接着计算7月最后一天,7月31号是周一,那么它应该在这个位置

这样一个完整的矩形(日历)在数据的角度上来说就齐全了;

四、代码实现

4.1 本月日期计算

关于本月日期的计算分为两部分,第一部分,获取当前日期,第二部分 获取本月1号的星期

先是获取当前日期

// 获取当前日期
function getCurrent() {
    const date = new Date();
    return [date.getFullYear(), date.getMonth() + 1, date.getDate()];
}

先是获取本月,很简单

/**
 * 获取公历某一天是星期几
 * @param {number} y 年
 * @param {number} m 月
 * @param {number} d 日
 * @returns {number} 返回星期数字[0-6]
 */
function solarWeek(y: number, m: number, d: number) {
  let date = new Date(y, m - 1, d);
  let week = date.getDay();
  return week;
}

const currentDate = getCurrent()
// 使用
this.solarWeek(currentDate[0], currentDate[1], 1)

这样我们就获取到了第一天是周几了;

4.2 上月日期补齐

关于上月数据获取有一点是需要注意的是,那就是如果当前是1月份,那么要获取的上上一年度的12月份,因此,在计算前首先要对当前月份进行确定

// 判断年度
const y = date[1] === 1 ? date[0] - 1 : date[0];
// 判断月份
const m = date[1] === 1 ? 12 : date[1] - 1;

接着就是判断需要补齐日期的数量了,很简单,我们只需要根据周几来判断,如果是周六,那么就是补齐6天(周一到周五,加上周日),如果是周五,那么就是补齐5天(周一到周四,加上周日);

 /**
   * 获取当月前面需补齐的数组
   */
beforDays(date: number[], last: number) {
    const y = date[1] === 1 ? date[0] - 1 : date[0];
    const m = date[1] === 1 ? 12 : date[1] - 1;

    const arr: dateBase[] = [];
    for (let i = 0; i < last; i++) {
        arr.push({...});
    }
    return arr;
}

这个last就是就是1号的星期,也就是需要循环的次数;

4.3 下个月日期补齐

接着补齐下个月,和上个月计算一样,首先要判断当前是不是12月,如果是12月,那么下个月就是下一年的1月份

const y = date[1] === 12 ? date[0] + 1 : date[0];
const m = date[1] === 12 ? 1 : date[1] + 1;

接着,由于我们知道了当前月的天数和上个月补齐的天数,那么自然下个月需要补齐多少天也能算出来,42-当前月天数-上个月天数=下个月补齐天数

/**
 * 获取当月后面需补齐的数组
 */
afterDays(day: dateBase[], date: number[]) {
    const arr: dateBase[] = [];
    const y = date[1] === 12 ? date[0] + 1 : date[0];
    const m = date[1] === 12 ? 1 : date[1] + 1;

    for (let i = 1; i < 42 - day.length + 1; i++) {
        arr.push({...});
    }
    return [...day, ...arr];
}

到这里,我们就可以获得一个长度为42的数组,这个数组代表从上月的倒数某一天到这个月再到下个月正数的某一天,一共42天;

4.4 转化成二位数组

为什么要转成二位数组,原因很简单,因为我们的这个日历从布局上来说它就是一个二位数组....一共有6行,每行都7格,对吧,因此需要转一下,转的代码也很简单

const dateArray = [];
for (let row = 0; row < 6; row++) {
    dateArray.push(allDate.splice(0, 7));
}

4.5 使用v-for生成日历

基本数据整理完成后,只需要通过Vue的v-for指令去批量生成格子即可;

<template v-if="TBody.length">
  <div
    class="t-calendar-row"
    v-for="(item, index) in TBody"
    :key="index"
    >
    <div
      class="t-calendar-col"
      v-for="(col, colIdx) in item"
      :key="colIdx"
      >
      <CalendarItem
        :col="col"
        :time="selectedTime"
        @changeTargetDate="changeDate"
        ></CalendarItem>
    </div>
  </div>
</template>
<template v-else>
  <div class="no-date">抱歉,暂无数据</div>
</template>

至于每一个格子的样式,可以根据需求进行定制化;

4.6 农历,假期等

真正的日历肯定远不止这些基础数据,肯定还有包括:农历,节日,假期等等不同标注,这些都可以在计算的时候将当前日期对应的值一并算好,在通过v-for渲染的时候将对应的CSS样式渲染上去即可,比如在进行数据push的时候可以:

arr.push({
  // 日期
  title: w - i,
  // 是否本月
  isCurrent: false,
  // 是否节假日
  isHolidays: DateClass.getHolidays([y, m, w - i]),
  date: `${y}-${clockFactory(m)}-${clockFactory(w - i)}`,
  // 阴历
  lunars: lun,
  isNow: false,
  // 阳历节日,如国庆,元旦
  solarDay: DateClass.getSolarDay(m, w - i),
  // 农历节日,如中秋,春节,端午
  lunarDay: DateClass.getlunarDay(Number(l[0]), Number(l[1]), Number(l[2])),
  // 生肖
  animal: DateClass.getAnimal(Number(l[0])),
  // 星座
  astro: DateClass.toAstro(y, m, w - i),
  // 节气
  term: getTerm(Number(l[0]), m, w - i)
});

等等都是可以在数据处理的时候一并处理好;

五、小结

其实知道了日历的生成原理后,居然觉得日历也没有那么难实现,就是稍微麻烦了点,最终要实现成什么样子还需要根据实际需求而定;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/49925.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何彻底卸载VMware

目录 第一章、停止并卸载VMware程序1.1&#xff09;停止VMware有关的服务1.2&#xff09;打开任务管理器停止进程1.3&#xff09;卸载VMware程序 第二章、残留文件删除2.1&#xff09;打开注册表2.2&#xff09;删除注册表残留文件2.3&#xff09;C盘文件删除 友情提醒&#xf…

从分片传输到并行传输之大文件传输加速技术

随着大文件的传输需求越来越多&#xff0c;传输过程中也会遇到很多困难&#xff0c;比如传输速度慢、文件安全性低等。为了克服这些困难&#xff0c;探讨各种大文件传输加速技术。其中&#xff0c;分片传输和并行传输是两种比较常见的技术&#xff0c;下面将对它们进行详细说明…

MySQL之深入InnoDB存储引擎——物理文件

文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时&#xff0c;数据库会先去读一个配置参数文件&#xff0c;用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…

【Python】logging模块笔记

目录 日志级别 四个组件 记录器 处理器 处理器 格式化器 格式 用法1&#xff1a;小项目可以采用编程的方法 用法2&#xff1a;建议采用配置文件的方式 用法3&#xff1a; 字典配置 日志级别 #默认的日志输出为warning # 使用baseConfig() 来指定日志输出级别 # 同时&#x…

【广州华锐互动】无人值守变电站AR虚拟测控平台

无人值守变电站AR虚拟测控平台是一种基于增强现实技术的电力设备巡检系统&#xff0c;它可以利用增强现实技术将虚拟信息叠加在真实场景中&#xff0c;帮助巡检人员更加高效地完成巡检任务。这种系统的出现&#xff0c;不仅提高了巡检效率和准确性&#xff0c;还降低了巡检成本…

【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

Nginx学习&#xff1a;HTTP核心模块&#xff08;九&#xff09;浏览器缓存与try_files 浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置&#xff0c;这一块也是 HTTP 的基础知识。之前我们就一直在强调&#xff0c;学习 Nginx 需要的就是各种网络相关的基础知识&…

C++设计模式笔记

设计模式 如何解决复杂性&#xff1f; 分解 核心思想&#xff1a;分而治之&#xff0c;将大问题分解为多个小问题&#xff0c;将复杂问题分解为多个简单的问题。 抽象 核心思想&#xff1a;从高层次角度讲&#xff0c;人们处理复杂性有一个通用的技术&#xff0c;及抽象。…

《重构的时机和方法》——让你的代码更健壮、更易维护

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

微服务体系<1>

我们的微服务架构 我们的微服务架构和单体架构的区别 什么是微服务架构 微服务就是吧我们传统的单体服务分成 订单模块 库存模块 账户模块单体模块 是本地调用 从订单模块 调用到库存模块 再到账户模块 这三个模块都是调用的同一个数据库 这就是我们的单体架构微服务 就是…

8.docker仓库

文章目录 Docker仓库本地私有仓库Docker HarborDocker harbor部署访问页面创建用户下载私有仓库镜像harbor同步 Docker仓库 本地私有仓库 ##先下载 registry 镜像docker pull registry##修改配置文件&#xff0c;在 daemon.json 文件中添加私有镜像仓库地址vim /etc/dock…

Windows使用Notepad++编辑Linux服务器的文件

&#x1f680; Windows使用Notepad编辑Linux服务器的文件 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介…

Verilog语法学习——LV2_异步复位的串联T触发器

LV2_异步复位的串联T触发器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述&#xff1a; 用verilog实现两个串联的异步复位的T触发器的逻辑&#x…

Mac 安装启动RabbitMq

使用HomeBrew安装 未安装的请参照我的这篇Mac安装HomeBrew文章 安装 执行命令 brew install rabbitmq启动方式 brew services start rabbitmq端口说明 端口用处5672RabbitMQ通讯端口&#xff0c;也就是连接使用的端口15672RabbbitMQ管理界面端口&#xff0c;需要开启Manage…

Django实现音乐网站 ⑴

使用Python Django框架制作一个音乐网站。 目录 网站功能模块 安装django 创建项目 创建应用 注册应用 配置数据库 设置数据库配置 设置pymysql库引用 创建数据库 创建数据表 生成表迁移文件 执行表迁移 后台管理 创建管理员账户 启动服务器 登录网站 配置时区…

图技术在 LLM 下的应用:知识图谱驱动的大语言模型 Llama Index

LLM 如火如荼地发展了大半年&#xff0c;各类大模型和相关框架也逐步成型&#xff0c;可被大家应用到业务实际中。在这个过程中&#xff0c;我们可能会遇到一类问题是&#xff1a;现有的哪些数据&#xff0c;如何更好地与 LLM 对接上。像是大家都在用的知识图谱&#xff0c;现在…

web APIs-练习一

轮播图点击切换&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"…

浅谈自动化测试

谈谈那些实习测试工程师应该掌握的基础知识&#xff08;一&#xff09;_什么时候才能变强的博客-CSDN博客https://blog.csdn.net/qq_17496235/article/details/131839453谈谈那些实习测试工程师应该掌握的基础知识&#xff08;二&#xff09;_什么时候才能变强的博客-CSDN博客h…

无涯教程-jQuery - Puff方法函数

吹气效果可以与show/hide/toggle一起使用。通过按比例放大元素并同时隐藏它&#xff0c;可以形成粉扑效果。 Puff - 语法 selector.hide|show|toggle( "puff", {arguments}, speed ); 这是所有参数的描述- model - 效果的模式。可以是"显…

【项目】轻量级HTTP服务器

文章目录 一、项目介绍二、前置知识2.1 URI、URL、URN2.2 CGI2.2.1 CGI的概念2.2.2 CGI模式的实现2.2.3 CGI的意义 三、项目设计3.1 日志的编写3.2 套接字编写3.3 HTTP服务器实现3.4 HTTP请求与响应结构3.5 EndPoint类的实现3.5.1 EndPoint的基本逻辑3.5.2 读取请求3.5.3 构建响…

iOS开发-聊天emoji表情与自定义动图表情左右滑动控件

iOS开发-聊天emoji表情与自定义动图表情左右滑动控件 之前开发中遇到需要实现聊天emoji表情与自定义动图表情左右滑动控件。使用UICollectionView实现。 一、效果图 二、实现代码 UICollectionView是一种类似于UITableView但又比UITableView功能更强大、更灵活的视图&#x…