vue3 自己写一个月的日历

效果图
在这里插入图片描述
在这里插入图片描述
代码

<template><div class="monthPage"><div class="calendar" v-loading="loading"><!-- 星期 --><div class="weekBox"><div v-for="(item, index) in dayArr" :key="index" class="weekTit">{{ item.label }}</div></div><!-- 天数 --><div class="itemBox" id="dateBox"><divv-for="(item, index) in dateArr":key="index":class="(selectDay === item.No) & item.show? 'select dateItem hoverItem': item.show? 'dateItem hoverItem': 'dateItem'"@click="selectOneDay(item, index)"><!-- 日历基本属性 --><div class="oneLabel" :class="day == item.No ? ' active' : ''" v-show="item.show"><div class="dayDesc" style="color: #ff4d4f" v-show=" item.isWeekday==0">休息日</div><div class="dayDesc">工作日</div><div class="dateNo">{{ item.No }}</div></div><!-- 考勤标签 --><div class="twoLabel"><!-- 异常 --><div class="labelColor yichang" v-show="index===14"><i class="iconfont icon-icon_yichang"></i><span>9</span></div><!-- 排班 --><div class="labelColor banci" v-show="index===14"><i class="iconfont icon-icon_banci"></i><span>6</span></div><!-- 加班 --><div class="labelColor jiaban" v-show="index===14"><i class="iconfont icon-icon_jiaban"></i><span>2</span></div><!-- 外出 --><div class="labelColor waichu" v-show="index===14"><i class="iconfont icon-icon_waichu"></i><span>5</span></div><!-- 休假 --><div class="labelColor xiujia" v-show="index===14"><i class="iconfont icon-icon_xiujia"></i><span>1</span></div><!-- 权限 --><div class="labelColor quanxian" v-show="index===15"><i class="iconfont icon-icon_quanxian"></i><span>3</span></div><!-- 节假日 --><div class="labelColor festivalBg" v-show="index===15"><div><i class="iconfont icon-icon_danju"></i></div><span>2</span></div><!-- 节假日加班 --><div class="labelColor OvertimeBg" v-show="index===15"><div><i class="iconfont icon-icon_danju"></i></div><span>2</span></div></div><!-- 非本月日期 --><div v-show="!item.show" class="oneLabel noData"><div class="dateNo">{{ item.No }}</div></div></div><!-- 弹出窗 --><div class="bubbleBox" v-show="bubbleFlag" :style="'top:' + top + 'px;left:' + left + 'px'"><div style="display:flex"><el-input v-model="dayFestival" placeholder="Please enter" style="margin-right:15px"></el-input><el-button type="primary" @click="setFestival">确认</el-button></div><span class="spanleft" v-show="leftOrRight"></span><span class="spanRight" v-show="!leftOrRight"></span></div></div></div></div>
</template><script>
import { onMounted, reactive, toRefs, watch, getCurrentInstance } from 'vue'
export default {setup () {const { proxy } = getCurrentInstance()const data = reactive({year: '', // 年month: '', // 月day: '',lastDay: '',dayArr: [{ label: "星期日", value: 7 },{ label: "星期一", value: 1 },{ label: "星期二", value: 2 },{ label: "星期三", value: 3 },{ label: "星期四", value: 4 },{ label: "星期五", value: 5 },{ label: "星期六", value: 6 }],dateArr: [], // 当前月份的天数selectDay: null,prevMonth: '',bubbleFlag: false,top: 0,left: 0,leftOrRight: true,recordTypeList: [],organizationIdList: [],personIdList: [],loading: false,dayFestival: '',pageName: 'month',timeMove: ''})onMounted(() => {let date = new Date()data.year = date.getFullYear()data.month = date.getMonth()data.prevMonth = date.getMonth()data.day = addZero(date.getDate()) // 补零initDate()})const addZero = (date) => {return date.toString().padStart(2, '0')}const initDate = () => {data.dateArr = []//当前月存storelet monthStr = 'el.datepicker.month' + (Number(data.month) + 1)let firstDay = new Date(data.year, data.month, 1).getDay() // 当月第一天星期几data.lastDay = new Date(data.year, data.month, 0).getDate() // 当月最后一天let prevLastDate = new Date(data.year, data.prevMonth, 0).getDate() // 上月的最后一天let monthNum = new Date(data.year, data.month + 1, -1).getDate() + 1 // 每月天数let dateStr = data.year + '-' + addZero(Number(data.month) + 1) + '-'for (let i = 1; i < monthNum + 1; i++) {let dateS = dateStr + addZero(i)data.dateArr.push({ No: i, show: true, punchDate: dateS }) // 遍历添加当前月份的每一天}for (let i = 0; i < firstDay; i++) {data.dateArr.unshift({No: prevLastDate - i,show: false,punchDate: '',}) //向前填充日期}let len = 8 - (data.dateArr.length % 7)for (let i = 1; i < len; i++) {data.dateArr.push({ No: i, show: false, punchDate: '' }) // 向后填充日期}}//获取日历数据const getList = async () => {}//选择日期const selectOneDay = (row, index) => {let e = window.eventlet dateBox = document.getElementById('dateBox')let ww = dateBox.clientWidth / 7let indexk = (Number(index) + 1) % 7let dateBoxWidth = dateBox.clientWidth - 123 //宽度修正值let dateBoxHeight = dateBox.clientHeight + 10 //高度修正值let scrollTop = dateBox.scrollTopif (!row.show) {data.bubbleFlag = falsereturn}if (row.No === data.selectDay) {data.bubbleFlag = falsedata.selectDay = null} else {data.bubbleFlag = truedata.selectDay = row.Nolet topNum = e.layerY + scrollToplet letNum = ww * indexkif (letNum === 0) {data.leftOrRight = falseletNum = ww * 6 - 120} else {data.leftOrRight = true}data.left = letNumdata.top = topNum > dateBoxHeight ? dateBoxHeight : topNum}data.dayFestival = row.customFestivalName || row.festivalName}// 标签弹窗const handleDialog = (id, type, punchDate) => {}// 自定义假日const setFestival = async (row) => {data.bubbleFlag = false}//监听前进后退watch(() => data.timeMove,(val) => {if (data.pageName === 'month') {if (val === 'next') {data.prevMonth++if (Number(data.month) + 1 > 11) {data.month = 0data.year = Number(data.year) + 1} else {data.month = Number(data.month) + 1}initDate()} else if (val === 'prev') {data.prevMonth--if (Number(data.month) - 1 < 0) {data.month = 11data.year = data.year - 1} else {data.month = Number(data.month) - 1}initDate()} else if (val === 'today') {let date = new Date()data.year = date.getFullYear()data.month = date.getMonth()data.prevMonth = date.getMonth()data.day = addZero(date.getDate()) // 补零initDate()}}},{deep: true,})return {...toRefs(data), // 将 data 返回出去,就可以直接使用 data 里面的属性selectOneDay,getList,handleDialog,initDate,setFestival,}},
}
</script><style scoped lang="scss">
.monthPage {display: flex;align-items: center;justify-content: center;flex-direction: column;height: 79vh;.calendar {width: 100%;height: 100%;background-color: #fff;// display: flex;// flex-wrap: wrap;.weekBox {height: 36px;display: flex;// flex-wrap: wrap;.weekTit {width: calc(100% / 7);padding-left: 10px;font-size: 14px;color: #606266;height: 36px;line-height: 36px;border-bottom: 1px solid #e4e7ed;}}.itemBox {height: 100%;overflow: scroll;display: flex;flex-wrap: wrap;padding-bottom: 30px;position: relative;.dateItem {width: calc(100% / 7);height: 158px;padding-left: 10px;color: #404040;font-size: 20px;box-sizing: border-box;border: 2px solid transparent;border-bottom: 2px solid #e4e7ed;padding: 9px;// position: relative;cursor: pointer;display: flex;justify-content: space-between;flex-direction: column;.oneLabel {width: 100%;height: 24px;margin-bottom: 4px;.dayDesc {color: #888888;font-size: 12px;float: right;text-align: right;}.dateNo {font-size: 20px;color: #404040;}}.active {.dayDesc {color: #1890ff;}.dateNo {color: #1890ff;}}.noData {float: left;width: calc(100% + 18px);height: 158px;margin: -9px;background: #f6f8f9;padding: 9px;cursor: default;}.twoLabel {width: calc(100% - 18px);display: flex;justify-content: space-between;flex-wrap: wrap-reverse;align-content: flex-end;height: auto;.labelColor {width: 49%;height: 24px;line-height: 24px;padding: 0 7px;font-size: 12px;margin-bottom: 4px;border-radius: 2px;padding: 0 7px;display: flex;justify-content: space-between;color: #ffffff;position: relative;z-index: 10;cursor: pointer;}}}.hoverItem {&:hover {border: 2px solid #1890ff;}}.select {background-color: #1890ff;border-color: #1890ff;.oneLabel {.dayDesc {color: #fff;}.dateNo {color: #fff;}}}.bubbleBox {padding: 7px 17px;box-sizing: border-box;position: absolute;top: 0;left: 0;background: #fff;z-index: 22;border-radius: 3px;box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.34);p {width: 100%;height: 26px;line-height: 26px;cursor: pointer;&:hover {color: #1890ff;}}.spanleft {position: absolute;left: -10px;top: 10px;width: 0;height: 0;border: 5px solid transparent;border-right: 5px solid #fff;z-index: 2;}.spanRight {position: absolute;right: -10px;top: 10px;width: 0;height: 0;border: 5px solid transparent;border-left: 5px solid #fff;z-index: 2;}}}}
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于马达保护器 的选型 你知道吗

一、智能马达保护器的介绍 在有色冶炼中&#xff0c;根据工艺需求和客户需求&#xff0c;智能电动机保护器的主要应用模式有保护模式、端子控制模式、全通信模式和半通信模式。 4.1保护模式 在保护模式下&#xff0c;智能电动机保护器只利用其自身的保护功能和测量功能&#…

T天池SQL训练营(五)-窗口函数等

–天池龙珠计划SQL训练营 5.1窗口函数 5.1.1窗口函数概念及基本的使用方法 窗口函数也称为OLAP函数。OLAP 是OnLine AnalyticalProcessing 的简称&#xff0c;意思是对数据库数据进行实时分析处理。 为了便于理解&#xff0c;称之为窗口函数。常规的SELECT语句都是对整张表进…

CSS新手入门笔记整理:CSS超链接样式

超链接伪类 超链接在鼠标单击的不同时期的样式是不一样的。 默认情况下&#xff1a;字体为蓝色&#xff0c;带有下划线。鼠标单击时&#xff1a;字体为红色&#xff0c;带有下划线。鼠标单击后&#xff1a;字体为紫色&#xff0c;带有下划线。 超链接伪类简介 在CSS中&…

【深度学习】注意力机制(二)

本文介绍一些注意力机制的实现&#xff0c;包括EA/MHSA/SK/DA/EPSA。 【深度学习】注意力机制&#xff08;一&#xff09; 【深度学习】注意力机制&#xff08;三&#xff09; 目录 一、EA&#xff08;External Attention&#xff09; 二、Multi Head Self Attention 三、…

Vue笔记-在axios中的than函数中使用this需要注意的地方

在Vue中&#xff0c;可以使用this关键字来访问到组件中定义的变量。然而&#xff0c;在axios的then函数中&#xff0c;this关键字的作用域会改变&#xff0c;会指向axios对象本身而不是Vue组件实例。因此&#xff0c;不能直接访问到Vue组件中定义的变量。 解决这个问题的一种方…

DevOps搭建(七)-安装Jenkins详细步骤

这里我们用Docker进行安装 1、拉取Jenkins镜像 Jenkins download and deployment 选择LTS长期支持的版本,接着点击Docker链接进入 找到上面的版本,并copy拉取镜像的命令 docker pull jenkins/jenkins:2.426.1-lts 2、docker-compose安装Jenkins 首先创建安装目录/home/f…

项目记录:SpringBoot+Vue部署在阿里云服务器

目录 一、服务器配置 二、后端代码打包 三、前端项目打包 四、nginx配置 一、服务器配置 部署项目需要一个服务器&#xff0c;我们可以选择阿里云的云服务器ECS&#xff0c;在实例界面可以对服务器进行管理&#xff1a; 然后需要在mobaxterm配置jdk、mysql和nginx。注意配…

【计算机网络】HTTP响应报文Cookie原理

目录 HTTP响应报文格式 一. 状态行 状态码与状态码描述 二. 响应头 Cookie原理 一. 前因 二. Cookie的状态管理 结束语 HTTP响应报文格式 HTTP响应报文分为四部分 状态行&#xff1a;包含三部分&#xff1a;协议版本&#xff0c;状态码&#xff0c;状态码描述响应头&a…

Vue实现注册页面的用户交互

&#x1f4d1;前言 本文主要是【Vue】——Vue实现注册页面的用户交互的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每…

基于TCP的多路复用

1. 知识点 目前支持I/O多路复用的系统调用有select&#xff0c;pselect&#xff0c;poll&#xff0c;epoll。与多进程和多线程技术相 比&#xff0c;I/O多路复用技术的最大优势是系统开销小&#xff0c;系统不必创建进程/线程&#xff0c;也不必维护这些进 程/线程&#xff0c;…

class073 背包dp-01背包、有依赖的背包【算法】

class073 背包dp-01背包、有依赖的背包【算法】 算法讲解073【必备】背包dp-01背包、有依赖的背包 code1 P1048 [NOIP2005 普及组] 采药 // 01背包(模版) // 给定一个正数t&#xff0c;表示背包的容量 // 有m个货物&#xff0c;每个货物可以选择一次 // 每个货物有自己的体积…

想进阶JAVA高级程序员吗?多线程必学

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星评选TOP 10&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作…