vue2 + moment 实现日历,并带有上个月和下个月日期的日历

news2024/11/14 15:07:15

在 Vue 2 中使用 moment 库绘制一个带有上个月和下个月日期的日历,可以通过以下步骤实现。这个日历将显示当前月份的天数,以及前一个月和下一个月的部分日期(通常为了让日历对齐为6行,每行7天)。

主要步骤:

  1. 生成当前月份的所有天数。
  2. 计算上个月的剩余天数(即填充当前月份开始前的日期)。
  3. 计算下个月的天数(即填充当前月份结束后的日期,直到日历的最后一天)

实现效果

在这里插入图片描述

代码实现

  1. 安装 moment
    首先,确保已经安装 moment 库:
npm install moment
  1. 在 Vue 组件中绘制日历
<template>
  <div class="calendar">
    <div class="calendar-top flex">
      <div class="calendar-top-same">
        <div>{{ month.format("YYYY年MM月") }}</div>
      </div>
      <el-button @click="prevMonth" size="mini">上个月</el-button>
      <el-button @click="currentMonth" size="mini">今天</el-button>
      <el-button @click="nextMonth" size="mini">下个月</el-button>
    </div>
    <div class="calendar-body">
      <div v-for="item in weekdays" :key="item" class="calendar-body-week">
        {{ item }}
      </div>
      <div
        v-for="(day, index) in days"
        :key="index"
        class="calendar-body-day"
        :class="{
          dis: day.isPrevMonth||day.isNextMonth,
          today:today===day.date.format('YYYY-MM-DD')
        }"
        @click="handleClickDay(day)"
      >
          {{ day.date.date() }}
      </div>
    </div>
  </div>
</template>

<script>
import moment from "moment";
export default {
  name: "calendar",
  props: {
    // 日期
    date: {
      type: Date,
      default() {
        return new Date();
      },
    },
  },
  data() {
    return {
      today: '', // 选中的日期
      month: moment(), // 当前月份
      weekdays: ["日", "一", "二", "三", "四", "五", "六"], // 星期
      days: [], // 存储当前日历显示的天数
    };
  },
  mounted() {
    this.today = moment(this.date).format("YYYY-MM-DD");
    this.generateCalendar();
  },
  methods: {
    // 生成日历
    generateCalendar() {
      this.days = [];
      // 获取当前月份的开始和结束日期
      const startOfMonth = this.month.clone().startOf("month");
      const endOfMonth = this.month.clone().endOf("month");

      // 获取上个月需要显示的天数
      const startWeekday = startOfMonth.day();
      const prevMonthDays = [];
      if (startWeekday > 0) {
        const prevMonthEnd = startOfMonth
          .clone()
          .subtract(1, "month")
          .endOf("month");
        for (let i = startWeekday - 1; i >= 0; i--) {
          prevMonthDays.push({
            date: prevMonthEnd.clone().subtract(i, "days"),
            isPrevMonth: true,
          });
        }
      }
      // 获取当前月份的所有天数
      const currentMonthDays = [];
      for (let i = 0; i < endOfMonth.date(); i++) {
        currentMonthDays.push({
          date: startOfMonth.clone().add(i, "days"),
          isPrevMonth: false,
          isNextMonth: false,
          // 是否为今天
          isToday: startOfMonth.clone().add(i, "days").isSame(moment(), "day"),
          // 是否为今天之后的日期 不含今天
          isAfterToday: startOfMonth.clone().add(i, "days").isAfter(
            moment(),
            "day",
          )
        });
      }
      // 获取下个月需要显示的天数
      const endWeekday = endOfMonth.day();
      const nextMonthDays = [];
      if (endWeekday < 6) {
        for (let i = 1; i <= 6 - endWeekday; i++) {
          nextMonthDays.push({
            date: endOfMonth.clone().add(i, "days"),
            isNextMonth: true,
            isAfterToday: endOfMonth.clone().add(i, "days").isAfter(
            moment(),
            "day",
          )
          });
        }
      }
      // 合并上个月、当前月份、下个月的天数
      this.days = [...prevMonthDays, ...currentMonthDays, ...nextMonthDays];
    },
    // 切换到上个月
    prevMonth() {
      this.month = this.month.clone().subtract(1, "month");
      this.generateCalendar();
    },
    // 切换到当前月份
    currentMonth() {
      this.today = moment().format("YYYY-MM-DD");
      this.month = moment();
      this.generateCalendar();
      this.$emit("change",this.today)
    },
    // 切换到下个月
    nextMonth() {
      this.month = this.month.clone().add(1, "month");
      this.generateCalendar();
    },
    // 今天之前触发
    handleClickDay(day){
      if(day.isAfterToday) return;
      this.today = day.date.format("YYYY-MM-DD");
      this.$emit("change",this.today)
    }
  },
};
</script>

<style lang="scss" scoped>
.calendar {
  user-select: none;
  &-top {
    justify-content: space-between;
    border: 1px solid #ccc;
    align-items: center;
    font-size: 14px;
    &-same {
      flex: 1;
      text-align: center;
    }
  }
  &-body {
    font-size: 14px;
    padding: 5px;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    &-week {
      background: #f5f7fa;
      cursor: progress;
    }
    > div {
      margin: 2px;
      text-align: center;
      border: #ccc solid 1px;
      padding: 5px;
    }

    &-day {
      cursor: pointer;
      .km {
        font-size: 12px;
        line-height: 1;
        color: #333;
      }
      &.dis {
        color: #ccc;
        // cursor: not-allowed;
      }
      &.today {
        background: #66b1ff;
        color: #fff;
      }
    }
  }
}
</style>

解释:

  1. today:当前选中的日期,默认今天
  2. month:使用 moment 来追踪当前月份。
  3. generateCalendar:这个方法用来生成日历,包括上个月的部分日期、当前月份的日期和下个月的部分日期。
  4. prevMonthnextMonth: 点击按钮来切换月份。
  5. currentMonth:这个方法是用来跳回到今天。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外国药品位置检测系统源码分享

外国药品位置检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

C语言中值传递

C语言中&#xff0c;值传递的问题 #include <stdio.h> void modifyValue(int x) { x 10; // 修改的是x的副本&#xff0c;对原始数据无影响 printf("在函数中修改的结果是:%d\n",x); }int main() { int a 5; printf("Before: %d\n", a); modifyV…

【资料分析】刷题日记3

第一套 √ 考点&#xff1a;基期比重差很温柔的题 普通专科女生 占比 52.5% - 1.7% 50.8% 成人本专科女生 占比 57.8% - 4.6% 53.2% 相比降低了2.4% 知比重和部分量&#xff0c;求整体在花生老师的解法中体会啥叫适当约分 0.1899 / 47.8% / 87.5% 》0.19 / &#xff08;4…

碎纸片的自动拼接复原技术

摘要&#xff1a;破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成&#xff0c;准确率较高&#xff0c;但耗费大量人力财力及时间&#xff0c;效率很低。随着计算机技术的发展&#xff0c;人们试图…

机器人上的DPDK使用思考

引言 项目背景 人形机器人作为智能技术的集大成者&#xff0c;正逐步从科幻电影走进现实生活&#xff0c;广泛应用于工业制造、医疗健康、家庭服务等多个领域。在这一发展过程中&#xff0c;传感器技术的飞速发展和物联网技术的广泛应用&#xff0c;极大地提升了人形机器人对…

微服务实战:规则引擎Drools

1. 概述 * 规则引擎核心思想&#xff1a;将应用程序中的业务决策部分分离出来 * 使得业务规则的变更不需要修改项目代码、重启服务器就可以在线上环境立即生效 2. 执行流程 drools规则引擎由以下三部分构成&#xff1a; Working Memory&#xff08;工作内存&#xff09; Ru…

360手机黑科技“位置穿越”功能修复 360位置穿越使用

​ 360手机刷机 360手机黑科技 360手机位置穿越 360手机位置修复 360手机站&#xff1a;360os.top 资源免费下载: os.360os.top 备用资源站&#xff1a;360手机-360手机刷机RootTwrp 360手机位置穿越 360手机位置穿越‌&#xff0c;是一款虚拟定位软件&#xff0c;无需进行r…

做谷歌外链有什么基础的要求?

做谷歌外链建设时有几个基本的要求需要注意。首先&#xff0c;收录率很关键&#xff0c;只有被谷歌成功收录的外链才会对网站产生正面影响。如果一个外链没有被收录&#xff0c;那它基本上对提升排名没有任何帮助 外链的多样性也是至关重要的。获取来自不同网站和平台的链接能为…

双token无感刷新

文章目录 &#x1f7e2;双token无感刷新1、token过期续期的五种方案对比2、双token的基本概念3、双token无感刷新的原理4、双token无感刷新的实现方式5.前端实现 ✒️总结 &#x1f7e2;双token无感刷新 对于token无感刷新这个东西有复杂度的话&#xff0c;它主要在后端&#x…

网站建设的服务器该如何选择?

服务器的选择对于网站的稳定运行、性能表现以及成本控制至关重要。以下是一些关键的考虑因素&#xff0c;帮助你选择适合的服务器&#xff1a; 明确需求&#xff1a;你需要先明确网站的需求和目标。这包括确定服务器将用于托管什么样的应用&#xff08;如Web前端、应用服务器、…

C/C++:优选算法(持续更新~~)

一、双指针 1.1移动零 链接&#xff1a;283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操…

【算法】BFS 系列之 多源 BFS

【ps】本篇有 4 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1&#xff09;01 矩阵 .1- 题目解析 .2- 代码编写 2&#xff09;飞地的数量 .1- 题目解析 .2- 代码编写 3&#xff09;地图中的最高点 .1- 题目解析 .2- 代码编写 4&#xff09;地图分析 .1- 题…

103.运行tomcat的Tomcatstartup.bat时,终端打印的中文显示为乱码

目录 原因 解决方法 原因 当运行Tomcat的Tomcatstartup.bat时&#xff0c;如果终端中文显示为乱码&#xff0c;这通常是因为Tomcat使用的日志输出编码与Windows命令行默认的编码不匹配。 解决方法 针对这一问题&#xff0c;你可以尝试以下步骤来解决&#…

【Spring】IocDI详解(6)

本系列共涉及4个框架&#xff1a;Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点&#xff0c;根据序号学习即可。 有什么不懂的都可以问我&#xff0c;看到消息会回复的&#xff0c;可能会不及时&#xff0c;请见谅&#xff01;&#xff01; 目录 本系列共…

深度图可视化显示(kitti)

文章目录 前言一、读取深度值与图像1、深度值读取2、图像读取 二、深度图可视化1、深度图可视化代码2、深度图可视化结果展示 三、深度图在图像上可视化1、可视化代码2、可视化坐标显示 四、完整代码 前言 kitti数据是一个通用数据&#xff0c;有关kitti的深度图像内容我已有博…

扣子智能体实战:一键生成公众号图文,AI时代文盲也能写公众号,赚钱秘籍

文章目录 一&#xff0c;需求简述二&#xff0c;智能体制作1&#xff0c;智能体人设和技能2&#xff0c;流程开发2.1 设置开始节点2.2 增加一个生成标题的大模型节点2.3 增加一个代码节点 2.4 增加一个插件节点用以生成文章配图2.4 增加一个大模型节点-根据标题和思路生成文章大…

Excel--WPS 函数与公式技巧(轻松搞定各类排名)

一、直接按成绩或数值的排序&#xff08;rank函数轻松搞定&#xff09; 以上函数非常简单&#xff0c;记住两点&#xff1a; 1.rank排名同分作为同一名次&#xff0c;后面的名次需要占位&#xff0c;如&#xff0c;以上两个70分&#xff0c;同为第8名&#xff0c;那么第9名将被…

Shader 中的光源

1、Shader 开发中常用的光源属性 Unity当中一共支持四种光源类型&#xff1a; 平行光&#xff08;Directional&#xff09;点光源&#xff08;Point&#xff09;聚光灯&#xff08;Spot&#xff09;面光源&#xff08;Area&#xff09;— 面光源仅在烘焙时有用 不管光源类型到…

可视化工具箱-Visualization Toolkit(VTK)

一、Visualization Toolkit&#xff08;VTK&#xff09;简概 可视化工具箱&#xff08;VTK&#xff09;&#xff0c;是一个用于3D计算机图形、图像处理和科学可视化的开源软件系统&#xff0c;其包含C类库和Tcl/Tk、Java与python的解释型接口层。VTK支持各种可视化算法&#xf…

软设9.20

1 已知一个文件中出现的各字符及其对应的频率如下表所示。若采用定长编码&#xff0c;则该文件中字符的码长应为()。若采用Hufman编码&#xff0c;则字符序列“face”的编码应为()。 1.&#xff08;&#xff09; A.2 B.3 C.4 D.5 2.&#xff08;&#xff09; A.110001001101…