elementui 日历组件el-calendar使用总结
功能:
1.日历可以周视图、月视图切换;
2.点击月视图中日期可以切换到对应周视图;
3.点击周视图查看当日对应数据;
4.周、月视图状态下,点击前后按钮,分别切换对应上下的周、月;
5.点击回到今天,立即切回到周、月视图下对应的当日;
引用dayjs处理日期,结合el-calendar完美实现。
要注意的是,日历显示周的话,传的日期范围要按照计算所在星期,比如我们的需求是周日为每周起始日,那么就要给周日的日期和周六日期为起始日,月视图我不想再去计算日期范围了,就直接用了:value,注意用的不是v-model而是value,因为value是单向的,v-model是双向数据绑定了。

<template>
<div class="childContainer"><CompBar name="XX日历" iconName="rili.png" titleName="回到今天" @handleBarClick="nowCalendar"><div class="kalendar"><div class="kalendar-header"><span class="current-monuth"><i class="el-icon-caret-left" @click="showPrev"></i><i class="el-icon-caret-right" @click="showNext"></i></span><el-radio-group v-model="monthYear" size="mini"><el-radio-button label="周"></el-radio-button><el-radio-button label="月"></el-radio-button></el-radio-group></div><CalendarMonth v-if="monthYear==='月'" :calendarValue="monthDate" :selectDay="dayDate" :dateList="dateList" @getPlanList="getplanList"></CalendarMonth><CalendarWeek v-else :rangeArr="dateRange" :selectDay="dayDate" :dateList="dateList"
@getPlanList="getplanList"></CalendarWeek></div><tabs :class="monthYear==='月'?'monthTabs':'weekTabs'" v-model="activePlan" v-loading="isLoading"><el-tab-pane name="tabApplyEndPlan">
//此处是个列表
</el-tab-pane><el-tab-pane name="tabEndPlan"></el-tab-pane></tabs>
</template>
// 此处省略组件、接口引入
import dayjs from 'dayjs';
var weekplugin = require('dayjs/plugin/weekday');
dayjs.extend(weekplugin)// 此处省略,直接放核心代码
data(){return{activePlan:'tabApplyEndPlan',monthYear:'周', // 周、月视图切换,默认显示周monthDate:'', // 传后端参数 YYYY-MM,查视图上需要显示点的日期dayDate:'', // 传后端参数 YYYY-MM-DD,查视图下面对应的当日数据列表dateRange:[], // 周日历,传入周日历视图日期范围dateList:[], // 存放月数据,视图中需要显示点的日期}
},watch:{
// 比较简单,直接省略代码了,记录下逻辑
// 监听 monthDate、dayDate 值的改变,调用对应接口
},methods:{
showPrev() {// 上个月if (this.monthYear === '月') {this.monthDate = dayjs(this.monthDate).add(-1, 'month').format('YYYY-MM');// 需要判断当前选中日期是否属于当前月份let _dayDate = dayjs(this.dayDate).format('YYYY-MM');if (_dayDate === this.monthDate) {// 计算本周第一天let day1 = dayjs(this.dayDate).startOf('week').format('YYYY-MM-DD');// 计算本周最后一天let day2 = dayjs(this.dayDate).endOf('week').format('YYYY-MM-DD');this.dateRange = [day1, day2];} else {let day1 = dayjs(this.monthDate).startOf('month').startOf('week').format('YYYY-MM-DD');let day2 = dayjs(this.monthDate).startOf('month').endOf('week').format('YYYY-MM-DD');this.dateRange = [day1, day2]}}// 上星期if (this.monthYear === '周') {// 获取当前周视图let day1 = dayjs(this.dateRange[0]).add(-1, 'week').startOf('week').format('YYYY-MM-DD');let day2 = dayjs(this.dateRange[1]).add(-1, 'week').endOf('week').format('YYYY-MM-DD');this.monthDate = dayjs(this.dateRange[0]).add(-1, 'week').startOf('week').format('YYYY-MM');this.dateRange = [day1, day2]}},
showNext() {// 下个月if (this.monthYear === '月') {this.monthDate = dayjs(this.monthDate).add(1, 'month').format('YYYY-MM');// 需要判断当前选中日期是否属于当前月份let _dayDate = dayjs(this.dayDate).format('YYYY-MM');if (_dayDate === this.monthDate) {// 计算本周第一天let day1 = dayjs(this.dayDate).startOf('week').format('YYYY-MM-DD');// 计算本周最后一天let day2 = dayjs(this.dayDate).endOf('week').format('YYYY-MM-DD');this.dateRange = [day1, day2];} else {let day1 = dayjs(this.monthDate).endOf('month').startOf('week').format('YYYY-MM-DD');let day2 = dayjs(this.monthDate).endOf('month').endOf('week').format('YYYY-MM-DD');this.dateRange = [day1, day2]}}// 下星期if (this.monthYear === '周') {// 获取当前周视图let day1 = dayjs(this.dateRange[0]).add(1, 'week').startOf('week').format('YYYY-MM-DD');let day2 = dayjs(this.dateRange[1]).add(1, 'week').endOf('week').format('YYYY-MM-DD');this.monthDate = dayjs(this.dateRange[0]).add(1, 'week').startOf('week').format('YYYY-MM');this.dateRange = [day1, day2]}},
// 返回今日nowCalendar() {this.monthDate = dayjs(new Date()).format('YYYY-MM');this.dayDate = dayjs(new Date()).format('YYYY-MM-DD');let day1 = dayjs(new Date()).startOf('week').format('YYYY-MM-DD');let day2 = dayjs(new Date()).endOf('week').format('YYYY-MM-DD');this.dateRange = [day1, day2];this.activePlan = 'tabApplyEndPlan'},
// 周、月视图日期被点击处理方法getPlanList(date) {// console.log(this.monthYear)// console.log(date)this.dayDate = date.day;// 点击上、下月/周日期,不涉及视图的切换if (this.monthYear === '月') {if (date.type === 'next-month') {this.showNext()}if (date.type === 'prev-month') {this.showPrev()}}if (this.monthYear === '周') {let _month = dayjs(date.day).format('YYYY-MM');if (date.type === 'next-month') {if (_month !== this.monthDate) {this.monthDate = dayjs(date.day).format('YYYY-MM');}}if (date.type === 'prev-month') {if (_month !== this.monthDate) {this.monthDate = dayjs(date.day).format('YYYY-MM');}}}if (date.type === 'current-month') {this.monthYear = '周';// 计算本周第一天let day1 = dayjs(this.dayDate).startOf('week').format('YYYY-MM-DD');// 计算本周最后一天let day2 = dayjs(this.dayDate).endOf('week').format('YYYY-MM-DD');// 计算点击日期所在周第一天所属月this.monthDate = dayjs(day1).startOf('week').format('YYYY-MM');this.dateRange = [day1, day2];}},}
自定义日历样式(没有用日历原先的头,全部自己重写的,还不错):
::v-deep .kalendar {&-header {text-align: center;margin: 10px 16px 0 16px;.current-monuth {font-size: 16px;letter-spacing: 0;font-weight: 500;margin-left: 15%;color: #262626;font-family: PingFangSC-Medium;i {cursor: pointer;}}.el-radio-group {float: right;}.el-radio-button__orig-radio:checked + .el-radio-button__inner {background: #ffffff;box-shadow: -1px 0 0 0 transparent;border: 1px solid rgba(199, 0, 11, 1);font-family: PingFangSC-Medium;font-size: 12px;color: #c7000b;letter-spacing: -0.04px;font-weight: 500;}.el-radio-button__inner:hover {color: #c7000b;}}.calender-dot-box {width: 100%;bottom: -8px;position: absolute;span {width: 6px;height: 6px;margin-right: 3px;border-radius: 50%;display: inline-block;&:last-of-type {margin-right: 0;}}.endPlan {background-color: #d61212;}.applyEndPlan {background-color: #ffd100;}}.el-calendar {&__body {padding: 10px 16px;}.is-today {.el-calendar-day {.calender-date {width: 34px;height: 34px;margin: 0 auto;color: #ff534f;border-radius: 10px;background: #fff;box-shadow: none;}}}&__header {display: none;}.current {.el-calendar-day {color: #262626;}}.prev,.next {color: #bfbfbf;}&-day {padding: 0;font-weight: 700;font-size: 16px;letter-spacing: 0;text-align: center;position: relative;transition: color 0.3s;font-family: DINAlternate-Bold;}&-table {th {font-family: PingFangSC-Regular;font-size: 16px;color: #262626;letter-spacing: 0;text-align: center;line-height: 34px;font-weight: 400;padding: 0;&:last-of-type,&:first-of-type {color: #ff564e;}}td {border: none;&.is-selected {background-color: transparent;}}.el-calendar-day {height: 34px;line-height: 34px;&:hover {background-color: transparent;}.calendar-isSelected {width: 34px;height: 34px;margin: 0 auto;color: #fff;border-radius: 10px;background: #ff534f;box-shadow: 0px 0px 2px 0px rgba(238, 88, 64, 1);}}}}
再看看子组件里面,先看月的:
<template><!-- 月日历 --><el-calendar :value="calendarValue" :first-day-of-week="7" value-format="YYY-MM"><template slot="dateCell" slot-scope="{ date, data }"><div v-if="selectedDay === data.day" class="calendar-isSelected" @click="handleDate($event, date, data)">{{ date.getDate() }}</div><div v-else class="calender-date" @click="handleDate($event, date, data)">{{ date.getDate() }}</div><div class="calender-dot-box" @click="handleDate($event, date, data, 'dot')"><template v-for="(item) in dateLists"><span class="applyEndPlan" v-if="item.date === data.day && item.applyEndPlanNum > 0"></span><span class="endPlan" v-if="item.date === data.day && item.endPlanNum > 0"></span></template></div></template></el-calendar>
</template>
<script>
export default {components: {},name: "CalendarMonth",props: {selectedDay: {type: String,default: "",},calendarValue: {type: String,default: new Date(),},dateList: {type: Array,default: () => {return [];},},},watch: {dateList: {handler(list) {this.dateLists = list;},immediate: true,},},data() {return { monthDate: this.calendarValue, dateLists: [] };},created() { },methods: {handleDate(e, date, data) {this.$emit("getPlanList", data);},},
};
</script>
<style lang="scss" scoped></style>
周日历组件:
<template><!-- 周日历 --><el-calendar :range="rangeArr" :first-day-of-week="7" value-format="YYY-MM"><template slot="dateCell" slot-scope="{date,data}"><div v-if="selectedDay === data.day" class="calendar-isSelected" @click="handleDate($event, date, data)">{{ date.getDate() }}</div> <div v-else class="calender-date" @click="handleDate($event, date, data)">{{ date.getDate() }}</div><div class="calender-dot-box" @click="handleDate($event, date, data)"><template v-for="(item) in dateList"><span class="applyEndPlan" v-if="item.date === data.day && item.applyEndPlanNum > 0"></span><span class="endPlan" v-if="item.date === data.day && item.endPlanNum > 0"></span></template></div></template></el-calendar>
</template>
<script>
export default {components: {}, name: 'CalendarWeek', props: {selectedDay: {type: String, default: '',}, rangeArr: {type: Array,default: () => {return [];}}, dateList: {type: Array, default: () => {return [];}}}, data() {return {}}, created() {}, methods: {handleDate(e, date, data) {// console.log(e,date,data)this.$emit('getPlanList', data)},}
}</script>
<style lang="scss" scoped></style>
其实应该把日历组件二次封装一下,就不用单独再去写周、月日历子组件了,有空了可以试试。
不过不得不再吐槽一句,elementui的日历组件,给提供的API真心的少,功能很简单。。。
最终效果图:
月视图效果图:

月视图下,有时候会出现整整一行的灰色日期,看起来不是很美观,那么就需要操作dom,通过js判断,操作dom来处理。大概思路就是,先通过 document.querySelectorAll('.el-calendar-table__row') 获取到所有.el-calendar-table__row的元素节点lists,然后循环遍历这些节点,若其子元素class中含有.current,那么就说明是带有当月的日期,则不改变样式,若不含,则说明这整行都是前\后月的日期,那么就可以把该.el-calendar-table__row的css里面加上属性display:none。
周视图效果图:

相关文章:
elementui 日历组件el-calendar使用总结
功能: 1.日历可以周视图、月视图切换; 2.点击月视图中日期可以切换到对应周视图; 3.点击周视图查看当日对应数据; 4.周、月视图状态下,点击前后按钮,分别切换对应上下的周、月; 5.点击回到…...
RK3568 安卓12 EC20模块NOCONN没有ip的问题(已解决)
从网上东拼西凑找了不少教程,但是里面没有提到rillib.so需要替换,替换掉就可以上网了,系统也有4G图标了。 注意,这个rillib.so是移远提供的。把他们提供的文件放到rk3568_android_sdk/vendor/rockchip/common/phone/lib下&#x…...
【NLP自然语言处理】基于BERT实现文本情感分类
Bert概述 BERT(Bidirectional Encoder Representations from Transformers)是一种深度学习模型,用于自然语言处理(NLP)任务。BERT的核心是由一种强大的神经网络架构——Transformer驱动的。这种架构包含了一种称为自注…...
CSS选择器(1)
以内部样式表编写CSS选择器,其主要编写在<head></head>元素里,通过<style></style>标签来定义内部样式表。 基本语法为: 选择器{ 声明块 } 声明块:是由一对大括号括起来,声明块中是一个一个的…...
Claude 3.5 Sonnet模型发布,对比ChatGPT4o孰强孰弱
Anthropic 这家生而为打击 OpenAI 安全问题的公司,正式发布了Claude 3.5 Sonnet模型! 用官网的话就是: 今天,我们推出了 Claude 3.5 Sonnet,这是我们即将推出的 Claude 3.5 型号系列中的第一个版本。Claude 3.5 Sonne…...
MySQL 分库分表
分表 分表 将表按照某种规则拆分成多个表。 分表的使用原因 当数据量超大的时候,B-Tree索引效果很变差。 垂直分区 切分原则:把不常用或存储内容比较多的字段分到新的表中可使表存储更多数据。 原因,Innodb主索引叶子节点存储着当前行的所有信…...
AutoMQ 社区双周精选第十二期(2024.06.29~2024.07.12)
本期概要 欢迎来到 AutoMQ 第十一期双周精选!在过去两周里,主干动态方面,AutoMQ 跟进了 Apache Kafka 3.4.x BUG 修复,并进行了CPU & GC 性能优化,另外,AutoBalancing 的 Reporter 和 Retriever 也将支…...
Web开发:<div>标签作用
div作用 介绍基本用法特点和用途样式化示例嵌套示例与其他标签的对比总结 介绍 在Web开发中,<div> 标签是一个通用的容器元素,用于将HTML文档中的内容分组。它是一个块级元素,通常用于布局目的,因为它可以包含其他块级元素…...
如何使用unittest框架来编写和运行单元测试
Python 的 unittest 框架是用于编写和运行可重复的测试的一个强大工具。它允许你定义测试用例、测试套件、测试运行器和测试固件(fixtures),从而系统化地测试你的代码。以下是如何使用 unittest 框架来编写和运行单元测试的基本步骤ÿ…...
2024最新超详细SpringMvc常用注解总结
SpringMVC常用注解 控制器(Controller)相关注解: 1.Controller Controller 注解用于标识一个类为 Spring MVC 的控制器,它能够处理用户的请求并返回相应的视图或数据。通常与 RequestMapping 注解一起使用,以定义请求…...
Linux硬件中断(IRQ)的基础知识
目录 一、中断的概念1.1 什么是硬件中断1.2 中断类型二、中断处理的工作原理2.1 中断请求2.2 中断向量2.3 中断服务例程(ISR)2.4 上下文切换2.5 中断处理2.6 任务恢复三、中断处理的编程3.1 注册中断处理函数3.2 注销中断处理函数四、中断和系统性能4.1 中断风暴4.2 IRQ亲和性…...
DP讨论——适配器模式
学而时习之,温故而知新。 敌人出招(使用场景) 说是自己的程序对接第三方的库,但是自己的代码的接口设计完毕了,如何对接上? 你出招 适配器模式就是为此而生的——我觉得应该是该解决方法被命名为了适配…...
window下tqdm进度条
原代码是linux下运行,修改后可在window下运行。 #ifndef TQDM_H #define TQDM_H#include <chrono> #include <ctime> #include <numeric> #include <ios> #include <string> #include <cstdlib> #include <iostream> #i…...
记录些Redis题集(1)
Redis内存淘汰触发条件的相关配置如下: Redis通过配置项maxmemory来设定其允许使用的最大内存容量。当Redis实际占用的内存达到这一阈值时,将触发内存淘汰机制,开始删除部分数据以释放内存空间,防止服务因内存溢出而异常。 Redi…...
防火墙双机热备带宽管理综合实验
一、实验拓扑 二、实验要求 12,对现有网络进行改造升级,将当个防火墙组网改成双机热备的组网形式,做负载分担模式,游客区和DMZ区走FW3,生产区和办公区的流量走FW1 13,办公区上网用户限制流量不超过100M&am…...
【Redis】哨兵(sentinel)
文章目录 一、哨兵是什么?二、 哨兵sentinel文件参数三、 模仿主机redis宕机四、哨兵运行流程和选举原理SDOWN主观下线ODOWN客观下线 五、 使用建议 以下是本篇文章正文内容 一、哨兵是什么? 哨兵巡查监控后台master主机是否故障,如果故障了…...
2024年高职云计算实验室建设及云计算实训平台整体解决方案
随着云计算技术的飞速发展,高职院校亟需构建一个与行业需求紧密结合的云计算实验室和实训平台。以下是针对2024年高职院校云计算实验室建设的全面解决方案。 1、在高职云计算实验室的建设与规划中,首要任务是立足于云计算学科的精准定位,紧密…...
入门实战篇,利用PADS Layout画电阻电容电感的封装
大家好,我是山羊君Goat。 不管怎么设计,怎么学习硬件知识,都需要实战,硬件工程师设计PCB是必不可少的(大部分来说),本篇主要从最基本的电阻电容电感的PCB设计封装来说起,算是最基础…...
解决npm install 安装报错记录贴
前言 环境背景 nodeJS v.14.8.3(nvm安装) package.json: “node-sass”:“8.0.0” 网络环境: 公司内网 镜像地址:公司的镜像源 解决报错过程: 1.换了最新版 vscode, 然后重装 node_modules 还是不行, 报PostCSS rec…...
CollectionUtils的使用
1、非空判断 判断集合是否为空 List<String>对象list,可以使用CollectionUtils中的isEmpty方法来判断list是否为空。代码如下 List<String> list new ArrayList<>(); boolean isEmpty CollectionUtils.isEmpty(list); System.out.println(is…...
深度学习工程化实战:从论文思想到可部署代码的七步法
1. 项目概述:这不是一份“论文清单”,而是一份深度学习演进的实操路线图你有没有过这种感觉:打开一篇讲“深度学习里程碑论文”的文章,满屏都是《AlexNet》《ResNet》《Transformer》这些名字,配着几句“开创性”“革命…...
从‘三调’到‘新国标’:深度解读用地分类演变背后的GIS数据处理逻辑与避坑指南
从‘三调’到‘新国标’:深度解读用地分类演变背后的GIS数据处理逻辑与避坑指南 当规划师第一次打开2020年11月版的《用地用海分类指南》,看到169种地类时,很多人会下意识倒吸一口冷气——这比2月版的132种足足多出37个细分项。这种"直男…...
C++位运算技巧应用
C位运算技巧应用位运算是直接操作二进制位的运算,具有极高的执行效率。掌握位运算技巧可以优化算法性能并实现紧凑的数据表示。基本位运算包括与、或、异或、取反和移位操作。#include #includevoid basic_bitwise_operations() { unsigned int a 0b1010; unsigned…...
从单机到团队协作:手把手教你用SVN在Windows上搭建个人小型项目版本库(含汉化与日常使用图解)
从单机到团队协作:Windows环境下SVN轻量化部署与实战指南 在个人开发和小型团队协作中,版本控制是保证代码安全和团队高效协作的基石。对于Windows平台的开发者而言,SVN(Subversion)以其简单可靠的特点,成为…...
【Midjourney印象派风格创作指南】:20年AI视觉专家亲授5大核心参数调优法,3步生成莫奈级画作
更多请点击: https://kaifayun.com 第一章:印象派美学与AI生成的底层耦合逻辑 印象派绘画摒弃精确轮廓与固有色,转而捕捉瞬时的光色颤动、视觉暂留与感知模糊性——这种对“未完成感”“概率性呈现”和“感知优先于表征”的推崇,…...
Amphenol ICC线束MSPEC6P2A5010应用与替代分析
随着工业通信、车载网络以及高速数据互联的发展,越来越多设备开始采用高性能线束组件来保证数据稳定传输。在工业自动化与智能设备领域,Amphenol ICC推出的MSPE系列近年来关注度持续提升,其中MSPEC6P2A5010就是比较典型的一款工业级线束组件。…...
从文字问诊到具身交付:健康 Agent 产品落地实战
当健康 Agent 跳出冰冷文字框,升级为能开口、有表情、会互动的 3D 数字医生,产品体验会发生质变。本文完整记录:我如何用魔珐星云 SDK,把文字健康 Agent 落地为可交互数字员工的实战全过程。 一、产品痛点:健康 Agent&…...
嘉立创EDA:原理图到PCB学习总结
1.原理图: 关于原理图绘制可以看项目需要哪些板块,去网上搜索开源项目跟着上面一步一步绘制即可,或者利用豆包来一步一步生成板块 主要要注意: 电源要加电容进行滤除杂波 一般带有功能的引脚是3.3V不要输入5V到这些IO口降压芯…...
从用户一句话到任务完成:Hermes Agent 一次请求完整链路详解
一、先说结论:Hermes 不是“问一句答一句”的普通聊天框很多人理解 AI 应用时,会把它想成一个 Chatbot:用户发一句话,模型回一句话。但 Hermes Agent 的请求链路更像一个“任务操作系统”。用户的一句话进入系统后,Her…...
UE5安装避坑指南:从Launcher到C++编译的完整环境配置
1. 这不是“点下一步就行”的安装:UE5下载安装背后的真实门槛很多人第一次点开Epic Games官网,看到那个醒目的“Download Engine”按钮,下意识觉得:“不就是个游戏引擎安装包?跟装微信、装PS差不多,双击→下…...
