-.- 废话补多说,直接上代码

<template><div class="calendar"><slot name="header"><div class="top"><div class="current">{{ time }}</div><div class="box"><div class="btn" @click="btn('prevMonth')">上个月</div><div class="btn" @click="btn('currentMonth')">当前月</div><div class="btn" @click="btn('nextMonth')">下个月</div></div></div></slot><div class="date"><div class="item">日</div><div class="item">一</div><div class="item">二</div><div class="item">三</div><div class="item">四</div><div class="item">五</div><div class="item">六</div><template v-for="(item,index) in list"><div class="item" :class="{active:item.type === currentSelectDate,current:currentDate == item.type,grey:item.next||item.prve}" :key="item.type" @click="click(item)"><slot :index="index" :item="item">{{ item.date }}</slot></div></template></div></div>
</template>
<script>
export default {name: "Calendar",props: {value: { type: Date, default: () => new Date() },},data() {return {list: [],time: "",currentSelectDate: "",currentDate: "",timeData: {},};},watch: {value(a) {if (a) this.time = a;this.btn(0);},timeData(a) {this.getData(a)},},created() {this.btn();},methods: {// 点击取当前时间-可以做一些操作getData(item){console.log(item);},click(item) {this.timeData = item;if (this.currentSelectDate === item.type) {// 取消选中this.currentSelectDate = "";// 选中日期} else this.currentSelectDate = item.type;// 选中日期是上个月if (item.next) this.btn("nextMonth");// 选中日期是下个月if (item.prve) this.btn("prevMonth");this.$emit("click", { ...item, selectDate: this.currentSelectDate });this.$emit("update:select-date", this.currentSelectDate);},// 默认当前月btn(type = "currentMonth") {// 获取指定时间的年份和月份let currentYear = new Date(this.time).getFullYear();let currentMonth = new Date(this.time).getMonth() + 1;// 点击上个月if (type === "prevMonth") {// 指定时间的月份为1月,上一月为上一年的12月if (currentMonth === 1)(currentMonth = 13), (currentYear = currentYear - 1);currentMonth--;}// 当前月if (type === "currentMonth") {// 获取当前时间的年月日currentYear = new Date().getFullYear();currentMonth = new Date().getMonth() + 1;let currentDate = new Date().getDate();this.currentDate = `${currentYear}-${currentMonth > 9 ? currentMonth : "0" + currentMonth}-${currentDate > 9 ? currentDate : "0" + currentDate}`;}// 下个月if (type === "nextMonth") {// 指定时间的月份为12月,下一月为下一年的1月if (currentMonth === 12)(currentMonth = 0), (currentYear = currentYear + 1);currentMonth++;}// 当前日历展示的年月this.time = `${currentYear}-${currentMonth > 9 ? currentMonth : "0" + currentMonth}`;let date = `${currentYear}-${currentMonth > 9 ? currentMonth : "0" + currentMonth}-01`;this.init(date);this.$emit("change-month", { currentYear, currentMonth, type, date });this.$emit("update:current-date", this.currentDate);},// 生成日历日期,因每月开始和结束不是周日和周六,需要取上月月末和下月月初补满每周七天,所以生成的总天数共35-42天。init(time) {// 获得指定时间年月,月总天数let date = new Date(time);let currentYear = date.getFullYear(); // 年let currentMonth = date.getMonth() + 1; // 月let currentMonthDate = new Date(currentYear, currentMonth, 0).getDate(); // 当月总天数let list = new Array(currentMonthDate).fill().map((_, i) => ({year: currentYear,month: currentMonth,date: i + 1,}));// 获取上月,需要处理跨年let preMonth = currentMonth;if (preMonth === 1) (preMonth = 13), (currentYear = currentYear - 1);let beforeMonthDate = new Date(currentYear, preMonth - 1, 0).getDate(); // 上月总天数let beforeDate = new Date(`${currentYear}-${preMonth - 1}-${beforeMonthDate}`).getDay();for (let i = 0; i <= beforeDate; i++)list.unshift({prve: true,year: currentYear,month: preMonth - 1,date: beforeMonthDate - i,});// 获取下月,需要处理跨年let nextMonth = currentMonth;if (nextMonth === 12) (nextMonth = 0), (currentYear = currentYear + 1);let afterDate = 7 - ((currentMonthDate + beforeDate) % 7); // 下月月头for (let i = 1; i < afterDate; i++)list.push({next: true,year: currentYear,month: nextMonth + 1,date: i,});this.list = list.map((e, i) => {let { year, month, date } = e;return {...e,week: Math.floor(i % 7),type: `${year}-${month > 9 ? month : "0" + month}-${date > 9 ? date : "0" + date}`,};});},},
};
</script>
<style lang='less' scoped>
.calendar {min-height: 300px;.top {display: flex;justify-content: space-between;align-items: center;height: 40px;margin: 0 0 20px 0;padding: 0 10px;}.box {display: flex;justify-content: space-evenly;width: 160px;border: 1px solid #eee;border-radius: 5px;margin: 5px;color: #666;.btn {padding: 3px 5px;cursor: pointer;transition: all 0.1s;&:nth-child(2) {border: 1px solid #eee;border-top: none;border-bottom: none;}&:hover {color: #333;background: #eee;transition: all 0.1s;}}}.item {flex: 0 0 13%;height: 35px;margin: 2px;min-width: 20px;text-align: center;color: #444;padding-top: 5px;box-sizing: border-box;border-radius: 5px;transition: all 0.2s;&.grey {color: #999;}&:hover {transition: all 0.2s;cursor: pointer;background: #5164e7a0;color: #fff;}&.current {transition: all 0.2s;background: #5164e7a0;color: #fff;}&.active {transition: all 0.2s;background: #5164e7;color: #fff;}}.date {display: flex;justify-content: space-between;align-items: center;flex-wrap: wrap;}
}
</style>

参考:https://www.jianshu.com/p/85cf4b3b5ba8

vue 绘制提醒日历组件相关推荐

  1. vue移动端日历组件 mintUi dateTime picker 设定开始和结束日期

    vue移动端日历组件 mintUi dateTime picker 设定开始和结束日期

  2. 基于Vue开发一个日历组件

    最近在做一个类似课程表的需求,需要自制一个日历来支持功能及展现,就顺便研究一下应该怎么开发日历组件. 更新 2.23修复了2026年2月份会渲染多一行的bug,谢谢@深蓝一人童鞋提出的bug,解决方案 ...

  3. vue封装一个日历组件

    图示 封装的组件的代码如下 <template><div class="calendar"><!-- 选择日历的弹出层 --><div c ...

  4. 用vue 编写一个日历组件(非常详细-让日历简单起来)

    相信有不少小伙伴和我一样一提到日历就脑壳疼,然后去网上搜索好用的日历组件,如element-ui什么的,但是日历毕竟是别人开发出来的, 和自己家ui设计出来的功能样式毕竟不能100%相似,所以这个时候 ...

  5. 从 0 到 1 用 Vue 封装一个日历组件

    写在前面 双手奉上代码链接: 传送门 - ajun568(https://github.com/ajun568/vue-calendar),点击文末阅读原文直达 双脚奉上最终效果图: 需求分析 需求分 ...

  6. vue dayjs 构造日历组件

    <template><!-- 选择年月 picker --><van-popup v-model:show="state.showTime" posi ...

  7. 学习笔记Vue(十 四)—— 用vue写一个日历组件

    先看一下实现的效果: 实现日历的逻辑: 先写出日历的大致结构,分两个部分,头部和主体部分,日历先显示6排7列,总共42个数字,按从1到42来显示: <div class="every- ...

  8. vue移动端日历组件

    <template><div id="calendar" :class="{'change':isChange}" ><!-- 年 ...

  9. vue展示日历 考勤展示_vue实现日历组件

    1.当前组件说明 一个用vue实现的简单日历组件,可以手动设置日历的宽高,未设置时,有默认宽高,设置后,其中的每个日期项的宽高可以根据设定的宽高自适应.可以设置当前选中日期,可以设置时间可用范围,可以 ...

最新文章

  1. Oracle下绝对文件号和相对文件号区别
  2. 在 Pycharm下使Python2和Python3共用Anaconda中的各种库/包的解决方法
  3. 【LeetCode】剑指 Offer 50. 第一个只出现一次的字符
  4. MySQL用户管理和权限设置
  5. 荣耀Magic2 发布:滑盖全面屏、前后6摄、屏下指纹、麒麟980
  6. 固态硬盘使用一段时间后测速变慢的解决方法
  7. linux PCI/PCIe驱动之pci_read_bases的理解
  8. 盈利能力分析之-毛利率、销售净利率、投资回报率、权益回报率、资产回报率...
  9. 计算机芯片级维修包括哪些,计算机芯片级维修中心(芯片级维培训教材)b.doc
  10. GPS的Heading, Course, and Crab Angle不同与区别
  11. python:2019新年贺词的词云制作以及基于TF-IDF的关键词提取
  12. 测试POST传输工具【poster】。
  13. 信息流广告投放的技巧
  14. 【问题解决】win服务器磁盘初始化
  15. 思科证书申请 CCNA CCNP CCIE
  16. matlab cell 颜色,MATLAB 的 cell 大法(单元格数组)
  17. Java计算数组中元素的总和
  18. 自考第三波+GCT考试总结
  19. webug 4.0 第二十二关 越权修改密码
  20. Docker 快速学习手册及相关笔记 附带一些问题解决方案

热门文章

  1. 使用 Prometheus 实现邮件/企业微信告警
  2. 楼宇对讲赶上智慧城市热潮 或迎来行业春天
  3. 解压工具BetterZip 有个操作队列功能 如何使用
  4. 国内外著名IT公司技术岗位要求
  5. 爬虫(3)——基于爬虫的天气报警器
  6. 华为USG系列防火墙能ping通不能打开网页的解决方案
  7. mysql查询男生基本情况_详解MySql基本查询、连接查询、子查询、正则表达查询...
  8. Oppo手机往电脑里拷贝照片时DCIM文件夹里照片显示不全的解决方案
  9. “吃鸡”游戏代理有搞头吗?
  10. p22 021 lambda表达式