momentJs推导日历组件

实现效果:

代码:

引入momentjs然后封装两个函数构建出基本数据结构

import moment from 'moment';

// 某月有多少天
export const getEndDay = (m) => m.daysInMonth();

/**
 * @description 获取本月空值数据
 *  @param { Date } year {  } 年度
 *  @param { Number } month 月份
 *  @param { Date } current moment当天日期
 */
export const getCalendar = ({ year, month, current }) => {
  // 最多6行, 每行为一周7天
  const totalDays = 7 * 6;
  // 获取这个月第一天具体日期
  const start = new Date(year, month - 1, 1);

  let lastEndDay = [];
  // 上个月的天数
  const lastDays = getEndDay(current.clone().subtract(1, 'month'));
  // 当前月的天数
  const nowDays = getEndDay(current);
  const currentDays = [...(new Array(nowDays))].map((v, i) => ({
    day: i + 1,
  })).map((v) => {
    const currentDate = v.day >= 10 ? `${moment(current).format('YYYY-MM')}-${v.day}` : `${moment(current).format('YYYY-MM')}-0${v.day}`;
    return {
      day: v.day,
      denyTime: moment().valueOf() > moment(`${currentDate} 23:59:59`).valueOf(),
      currentDate,
    };
  });
  if (start.getDay() === 0) {
    // 这个月1号为周日,则取上个月最后6天
    lastEndDay = [...new Array(lastDays)].map((v, i) => i + 1).filter((v) => v > lastDays - 6).map((v) => ({
      day: v,
      denyMonth: true,
    }));
  } else {
    lastEndDay = [...(new Array(lastDays))].map((v, i) => i + 1).filter((v, i) => i  > lastDays - start.getDay()).map((v) => ({
      day: v,
      denyMonth: true,
    }));
  }
  // 获取下个月补充天数
  const nextDays = [...new Array(totalDays - lastEndDay.length - currentDays.length)].map((v, i) => ({ day: i + 1, denyMonth: true }));
  const data = [...lastEndDay, ...currentDays, ...nextDays];
  return data;
};

页面代码部分:

<template>
  <div>
    <div class="flex-y-center flex-x-between border-t border-r border-l pad-y-xs pad-x-md">
            <div>{{ renderCalendarMonth }}</div>
            <div class="text-right">
              <el-button size="small" @click="handleMonth(1)">上个月</el-button>
              <el-button size="small" @click="handleMonth()">本月</el-button>
              <el-button size="small" @click="handleMonth(2)">下个月</el-button>
            </div>
          </div>
          <div class="border-a pad-a-sm">
            <div class="grid-week mar-b-sm">
              <div v-for="item in weekLabel" :key="item" class="text-center">
                {{ item }}
              </div>
            </div>
            <div class="grid-month-day">
              <div
                v-for="(item, idx) in CalendarDays"
                :key="idx"
                :class="{
                  'text-center': 1,
                  'grey-out-ban': item.denyMonth || item.denyTime,
                  'active': item.currentDate === activeDay
                }"
                @click="handleDay(item)"
              >
                {{ item.day }}
              </div>
            </div>
          </div>
</div>
</template>

import moment from 'moment';
import { getCalendar } from '../request';

export default {
 data() {
    return {
      weekLabel: ['一', '二', '三', '四', '五', '六', '七'],
      // 当前时间日历推导
      currentTime: moment(),
      // 日历挂表
      CalendarDays: [],
      // 选择日期
      activeDay: moment().format('yyyy-MM-DD'),
      // 月份切换
      activeMonth: 0,
    };
  },
computed: {
    // 日历具体年月份
    renderCalendarMonth() {
      const enumMonth = ['一', '二', '三', '四', '五', '六', '七', '八', '九',  '十', '十一', '十二'];
      const year = moment().subtract(this.activeMonth, 'months').format('yyyy');
      let month = moment().subtract(this.activeMonth, 'months').format('M');
      month = enumMonth[month - 1];
      return `${year}年${month}月`;
    },
  },
created() {
    this.init();
  },
  methods: {
    // 初始化
    init() {
      this.CalendarDays = getCalendar({
        year: moment().format('yyyy'), current: this.currentTime, month: moment().format('M'),
      });
    },
    // 月份切换
    handleMonth(type) {
      if (type) {
        if (type === 1) {
          this.activeMonth++;
        } else {
          this.activeMonth--;
        }
        const day = moment().subtract(this.activeMonth, 'months');
        this.CalendarDays = getCalendar({
          year: day.format('yyyy'),
          current: day,
          month: day.format('M'),
        });
      } else {
        this.activeMonth = 0;
        this.CalendarDays = getCalendar({
          year: moment().format('yyyy'), current: this.currentTime, month: moment().format('M'),
        });
        this.activeDay = moment().format('yyyy-MM-DD');
      }
    },
    handleDay(item) {
      if (item.denyMonth || item.denyTime) return;
      this.activeDay = item.currentDate;
    },
  },


};
</script>

<style lang="scss" scoped>
.grid-week, .grid-month-day {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 10px;
}

.grid-month-day {
  &>div {
    padding: 6px 0;
    box-sizing: border-box;
    border: 1px solid $base-border-color;
    &.grey-out-ban {
      background-color: #E9E9EB;
      cursor: not-allowed;
    }
    &:not(.grey-out-ban) {
      color: $base-color-primary;
      cursor: pointer;
    }
    &.active {
      border: 1px solid $base-color-primary;
      background-color: $base-color-primary;
      color: white;
    }
  }
}
</style>

结尾:这里贴代码就挺难受的,没有Vue只有html,果然这个时候用react就不错,不过思路已经提供了,先理清日历的每周对应天数结构,后面处理起来就容易许多。这里附上做的另一个日历效果图,代码就不贴了,js推导函数都差不多,不过是把日期天数的推导改下就可以了。

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

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

相关文章

【JS逆向六】(上)逆向模拟生成某网站的【sig】和【payload】的值 仅供学习

逆向日期&#xff1a;2024.02.07 使用工具&#xff1a;Node.js 加密方法&#xff1a;未知 / md5标准库 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 可使用AES进行解密处理&#xff08; 直接解密即可&#xff09;&#xff1a;在线AES加解…

shell脚本基础语法(.sh ./ sh bash source shell)

Linux 之 Shell 脚本基础语法 0. 学习一门语言的顺序 1. Shell 编程概述 1.1 Shell 名词解释 在 Linux 操作系统中&#xff0c;Shell 是一个命令行解释器&#xff0c;它为用户提供了一个与操作系统内核交互的界面。用户可以通过 Shell 输入命令&#xff0c;然后 Shell 将这些…

【Web - 框架 - Vue】随笔 - 通过`CDN`的方式使用`VUE 2.0`和`Element UI`

通过CDN的方式使用VUE 2.0和Element UI VUE 网址 https://cdn.bootcdn.net/ajax/libs/vue/2.7.16/vue.js源码 https://download.csdn.net/download/HIGK_365/88815507测试 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

echarts 一条折线图上显示不同颜色

文档树懒学堂&#xff1a;ECharts visualMap 代码实例及对应注释 - 树懒学堂 封装的echarts 组件代码&#xff1a; <template> <div :style"{ height: 100% }"> <div class"foldLine" ref"foldLine" :style"{ width: width…

【数据结构】链表OJ面试题3(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 9. 给定一个链表&#xff0c;判断链表中是否有环。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成…

工业以太网交换机引领现代工厂自动化新潮流

随着科技的飞速发展&#xff0c;现代工厂正迎来一场前所未有的自动化变革&#xff0c;而工业以太网交换机的崭新角色正是这场变革的关键组成部分。本文将深入探讨工业以太网交换机与现代工厂自动化的紧密集成&#xff0c;探讨这一集成如何推动工业生产的智能化、效率提升以及未…

UDP端口探活的那些细节

一 背景 商业客户反馈用categraf的net_response插件配置了udp探测, 遇到报错了&#xff0c;如图 udp是无连接的&#xff0c;无法用建立连接的形式判断端口。 插件最初的设计是需要配置udp的发送字符&#xff0c;并且配置期望返回的字符串&#xff0c; [[instances]] targets…

VSCode无法启动:Waiting for server log...

问题基本情况 [13:30:20.720] > code 1.86.0 (commit 05047486b6df5eb8d44b2ecd70ea3bdf775fd937) [13:30:20.724] > Running ssh connection command... /var/fpwork/reiss/vscdata/server/cplane/.vscode-server/code-05047486b6df5eb8d44b2ecd70ea3bdf775fd937 comman…

【RT-DETR有效改进】轻量级下采样方法ContextGuided(参数量下降700W,轻量又涨点)

&#x1f451;欢迎大家订阅本专栏&#xff0c;一起学习RT-DETR&#x1f451; 一、本文介绍 本文给大家带来的是改进机制是一种替换Conv的模块Context Guided Block (CG block) &#xff0c;其是在CGNet论文中提出的一种模块&#xff0c;其基本原理是模拟人类视觉系统依赖上…

centos 7.6 安装cas 对接ldap 单点登录实战

centos 7.6 安装cas 对ldap 单点登录实战 1、安装前准备工作1.1、centos 7.6 安装JDK 1.81.2、centos 7 安装tomcat 9.0.841.3、windows10 安装JDK 1.81.4、windows10 安装打包工具 maven 3.9.6 2、下载cas 5.3 并打包成war包3、部署cas到tomcat4、cas对接ldap 1、安装前准备工…

SQL注入讲解-BeesCMS系统漏洞分析溯源

判断网页框架 渗透思路 以前的思路 1.首先识别一下指纹 根据指纹查找历史漏洞(同样适用现在) 2.查找目录(目录里面会有很多惊喜) 通过御剑后台扫描工具找到文件夹后在网页打开文件夹进行测试 通过百度搜索查看历史漏洞 查看源代码发现它对账号和密码只有二个加密 我们通过bu…

LeetCode:26.删除有序数组中的重复项

26. 删除有序数组中的重复项 - 力扣&#xff08;LeetCode&#xff09; 目录 题目&#xff1a; 思路&#xff1a; 代码注释&#xff1a; 每日表情包&#xff1a; 题目&#xff1a; 思路&#xff1a; 没啥特殊的&#xff0c;老老实实双指针遍历数组&#xff0c;&#xff0…

谷歌seo搜索引擎优化教程有吗?

教程&#xff0c;教学&#xff0c;指南&#xff0c;这些东西哪里都有&#xff0c;尤其是关于seo相关方面的&#xff0c;这些可以说到处都是&#xff0c;能把谷歌seo这个关键词做上去的&#xff0c;可以说就是实力的证明了&#xff0c;在这里我们说一个无论是老手还是新手都应该…

archlinux 使用 electron-ssr 代理 socks5

提前下载好 pacman 包 https://github.com/shadowsocksrr/electron-ssr/releases/download/v0.2.7/electron-ssr-0.2.7.pacman 首先要有 yay 和 aur 源&#xff0c;这个可以参考我之前的博客 虚拟机内使用 archinstall 安装 arch linux 2024.01.01 安装依赖 yay 安装的&#…

Linux下centos操作系统安装Mysql8.0过程及踩坑填补

我自己有一台服务器&#xff0c;之前安装的是MySQL5.5&#xff0c;现在我想升级为MySQL8.0&#xff0c;于是我干了以下操作,既有踩坑又有干货&#xff1a; 1.先卸载MySQL&#xff1b; 2.删除跟MySQL相关文件&#xff1b; 3.安装新的MySQL8.0版本&#xff08;这里踩了一个坑&…

破除Github API接口的访问次数限制

破除Github API接口的访问次数限制 1、Github介绍2、Github API接口2.1 介绍2.2 使用方法 3、Github API访问限制3.1 访问限制原因3.2 访问限制类别 4、Github API访问限制破除4.1 限制破除原理4.2 限制破除示例 1、Github介绍 Github&#xff0c;是一个面向开源及私有软件项目…

VS2017+Qt中文无法编译通过newline in constant解决办法

首先说我的解决办法 Tools->Extensions and Updates… 安装ForceUTF8(with BOM) 注意Force这个插件有好几个版本&#xff0c;一定要withBOM&#xff01;&#xff01;&#xff01;我之前安装的没有BOM导致改了各种设置还是一直编译不过&#xff0c;差点没气死我 另外代码里…

Mac电脑删除第三方软件的最简单方法(2024最新教程)

Mac用户经常会下载各种第三方软件来提高工作效率或娱乐体验。然而&#xff0c;随着时间的推移&#xff0c;一些软件可能不再需要&#xff0c;或者用户可能想要清理空间。在这种情况下&#xff0c;有效地删除这些第三方软件变得尤为重要。本文将介绍几种常规的Mac删除第三方软件…

react+antd+CheckableTag实现Tag标签单选或多选功能

1、效果如下图 实现tag标签单选或多选功能 2、环境准备 1、react18 2、antd 4 3、功能实现 原理: 封装一个受控组件&#xff0c;接受父组件的参数&#xff0c;数据发现变化后&#xff0c;回传给父组件 1、首先&#xff0c;引入CheckableTag组件和useEffect, useMemo, use…

动态规划01 三步问题[C++]

​​​​​​ 图源&#xff1a;文心一言 上机题目练习整理&#xff0c;本篇作为动态规划的代码&#xff0c;因为做题入门很少找到带图的讲解&#xff08;难道是因为太简单&#xff0c;所以没有人嘛&#xff09;&#xff0c;所以干脆自己写一份&#xff0c;供小伙伴们参考~&am…