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">
        <div
          v-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 = []
      //当前月存store
      let 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.event
      let dateBox = document.getElementById('dateBox')
      let ww = dateBox.clientWidth / 7
      let indexk = (Number(index) + 1) % 7
      let dateBoxWidth = dateBox.clientWidth - 123 //宽度修正值
      let dateBoxHeight = dateBox.clientHeight + 10 //高度修正值
      let scrollTop = dateBox.scrollTop
      if (!row.show) {
        data.bubbleFlag = false
        return
      }
      if (row.No === data.selectDay) {
        data.bubbleFlag = false
        data.selectDay = null
      } else {
        data.bubbleFlag = true
        data.selectDay = row.No
        let topNum = e.layerY + scrollTop
        let letNum = ww * indexk
        if (letNum === 0) {
          data.leftOrRight = false
          letNum = ww * 6 - 120
        } else {
          data.leftOrRight = true
        }
        data.left = letNum
        data.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 = 0
              data.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 = 11
              data.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>

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

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

相关文章

认识计算机的设备管理

在计算机系统中&#xff0c;除了处理器和内存之外&#xff0c;其他的大部分硬设备称为外部设备。它包括输入/输出设备&#xff0c;辅存设备及终端设备等。这些设备种类繁多&#xff0c;特性各异&#xff0c;操作方式的差异很大&#xff0c;从而使操作系统的设备管理变得十分繁杂…

数据仓库工具Hive

1. 请解释Hive是什么&#xff0c;它的主要用途是什么&#xff1f; Hive是一个基于Hadoop的数据仓库工具&#xff0c;主要用于处理和分析大规模结构化数据。它可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类似SQL的查询功能&#xff0c;将SQL语句转换为MapRedu…

使用 iperf 和 iftop 测试网络带宽

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

京东商品详情数据在数据分析行业中的重要性

京东商品详情数据在数据分析行业中具有重要作用。这些数据提供了丰富的信息&#xff0c;可以帮助企业了解市场趋势、消费者需求、产品表现以及运营策略等多个方面。 首先&#xff0c;京东商品详情数据可以为企业提供市场趋势分析的依据。通过观察商品的销售量、销售额、价格等…

Qt 6.5 类库实例大全:QObject

大家好&#xff0c;我是20YC小二&#xff01;福利时间&#xff1a;欢迎(wx)扫码关注&#xff0c;免费领取《C程序员入门必修第一课&#xff1a;C基础课程》在线视频教程&#xff0c;还有更多技术分享&#xff01;#下面进入今天内容# 1. QObject 介绍 QObject 是 Qt 库中最重要…

RocketMq集成SpringBoot(待完善)

环境 jdk1.8, springboot2.7.3 Maven依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> <!-- lookup parent from…

C++学习笔记:继承

继承 什么是继承?继承的写法基类和派生类的赋值转换继承中的作用域派生类的默认成员函数单继承,多继承,虚拟继承is-a 和 has-a 什么是继承? 继承是C语言面向对象的三大特性之一&#xff0c;是面向对象程序设计使代码可以复用的最重要的手段,基本都是在一个类的基础上为了增加…

一个简单的可视化的A星自动寻路

一个简单的应用场景&#xff0c;流程图连线 源码&#xff1a; addExample("A星路径查找", function () {return {template: <div><div ref"main"></div></div>,data() { return {}; },computed: {},methods: {},mounted() {var c…

2-3、运算符

语雀原文链接 文章目录 1、算术运算符2、关系运算符3、逻辑运算符4、赋值运算符5、移位运算符6、位运算符(二进制位进行运算)7、条件运算符:三目运算符8、运算符的优先级 1、算术运算符 &#xff1a;加法-&#xff1a;减法*&#xff1a;乘法/&#xff1a;除法取商%&#xff1…

logback日志框架使用

依赖引入 <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version> </dependency> 使用logback日志框架只需要引入以上即可&#xff0c;(我们平时使用较多的Slf4j…

Fall in love with English

Fall in love with English 爱上英语 Hiding behind the loose dusty curtain, a teenager packed up his overcoat into the suitcase. 躲藏在布满尘土的松软的窗帘后边&#xff0c;一个年轻人打包他的外套到行李箱中。 He planned to leave home at dusk though there was th…

ssh免密登录及scp/rsync免密传输文件的方式

在通过ssh登录其它电脑或通过scp/rsync同其它电脑之间传输文件时&#xff0c;每次都需要输入密码&#xff0c;如下图所示&#xff1a;在windows10上通过ssh登录虚拟机&#xff0c;每次登录都需要输入密码&#xff1b;若端口默认为22,可省略通过-p指定 可通过将本机上的公钥key存…

熔池处理Tecplot 360 和CFD-Post做出一样的效果

熔池处理Tecplot 360 和CFD-Post做出一样的效果 效果展示详细讲述Tecplot 360实现过程分析实现过程第一步实现过程第二步界面美化注意点效果展示 详细讲述Tecplot 360实现过程 分析 这里主要是将体积分数大于0.5的区域抽取出来,然后显示温度场,所以这里主要考虑下面连个思考…

Agent相关工作调研

API Bank 要解决两个问题&#xff1a; 1)目前的LLM在使用工具方面的效果如何&#xff1f; 2) LLM使用工具还存在哪些障碍&#xff1f; 理想的效果&#xff1a;&#xff1a;通过访问全球工具存储库&#xff0c;LLM可以通过概述实现需求所需的所有步骤来帮助人们规划需求。随后…

你知道Java中的BigInteger类和BigDecimal类吗?

BigInteger和BigDecimal&#xff1a; 我们在学习JavaSE基础的时候学习过int和double&#xff0c;前者是整形&#xff0c;后者是双精度浮点数&#xff0c;但它们是有最大值的&#xff0c;也就是说&#xff0c;他两并不支持无限大的数字。 其范围如下所示&#xff1a; 因此对于…

图论-并查集

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图,求最小生成树Kruskal算法和最近公共祖先(LCA)等. 并查集的基本操作主要有: .1.初始化 2.查询find 3.合并union 一般我们都会采用路径压缩 这样…

Java期末复习题之分支循环

点击返回标题->23年Java期末复习-CSDN博客 第1题. 编写一个模拟同时掷骰子的程序。要用Math.random()模拟产生两个骰子&#xff0c;将两个结果相加&#xff0c;相加的和等于7的可能性最大&#xff0c;等于2和12的可能性最小。程序模投掷3600次&#xff0c;判断求和的结果是否…

在IDEA中创建Maven项目时没有src文件、不自动配置文件

错误示例&#xff1a; 没有src文件&#xff0c;并且没有自动下载相关的配置文件 对我这中情况无效的解决办法&#xff1a; ①配置好下列图中圈出来的文件 ②在VM选项中输入&#xff1a;“-DarchetypeInternal” ③点击应用&#xff0c;再点击确定 ④还是不行 解决办法&#x…

20 套监控平台统一成 1 套 Flashcat,国泰君安监控选型提效之路

author:宋庆羽-国泰君安期货 运维工作最重要的就是维护系统的稳定性&#xff0c;其中监控是保证系统稳定性很重要的一环。通过监控可以了解系统的运行状态&#xff0c;及时发现问题和系统隐患&#xff0c;有助于一线人员快速解决问题&#xff0c;提高业务系统的可用时长。 作为…

class064 Dijkstra算法、分层图最短路【算法】

class064 Dijkstra算法、分层图最短路【算法】 算法讲解064【必备】Dijkstra算法、分层图最短路 code1 743. 网络延迟时间 // Dijkstra算法模版&#xff08;Leetcode&#xff09; // 网络延迟时间 // 有 n 个网络节点&#xff0c;标记为 1 到 n // 给你一个列表 times&…