vue 自定义月日历日程组件(MSchedule)

2023-11-02

效果图

组件的使用 

  1. 日程内容可以自定义
  2. 状态对应颜色可以自定义
<MSchedule :scheduleList="plan" :isExpend="false" :hasNumExpend="3" @handleDetail="handleDetail" @chooseEntireCard="chooseEntireCard"
                   @changeMonth="changeMonth">
          <template v-slot:card="{row}">
            <span>时段:{{ row.timePeriod }}</span>
            <span>课程:{{ row.course }}</span>
          </template>
        </MSchedule>

下载组件 使用教程及参数点击这里

npm i mschedule -S

组件完整代码如下

html部分

<template>
  <div class="month-container">
    <div class="month-top">
      <div class="m-btn-wrap">
        <span @click="handleShowLastMonth">上一月</span>
        <span @click="handleShowToday"> 今天 </span>
        <span @click="handleShowNextMonth">下一月</span>
      </div>
      <span class="m-today-date"> {{ year }}年{{ month > 9 ? month : `0${month}` }}月</span>
      <div class="m-card-status">
        <div v-for="sta in cardStatus">
          <span class="square" :style="{background:sta.color}"></span>
          <span class="title">{{ sta.title }}</span>
        </div>
      </div>
    </div>
    <div class="m-date-wrap">
      <ul class="m-week">
        <li>日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
      </ul>
      <ul class="m-day">
        <li v-for="(item,index) in days"
            :class="{'m-isActive':item.isActive,'m-isCurToday':item.isCurToday}"
            :key="index">
          <span @click="handleChooseCard(item)" class="m-date" :class="{'m-isCurMonth':item.isNextMonth||item.isLastMonth}">
            {{ item.day }}
          </span>
          <template v-for="(plan,i) in item.planList">
            <div :key="`plan${i}`" @click="handleDetail(plan)"
                 class="m-card-default"
                 :style="{background: cardStatus[plan.status].color}">
              <slot name="card" :row="plan"></slot>
            </div>
          </template>
        </li>
      </ul>
    </div>
  </div>
</template>

js 部分  import MyTools from "../utils/MyTools"; 点击这里

<script>
import MyTools from "../utils/MyTools";

export default {
  name: 'monthSchedule',
  props: {
    list: {
      type: Array,
    },
    cardStatus: {
      type: Object,
      default: () => {
        return {
          1: {
            title: '已过期',
            color: '#9CADADB7'
          },
          2: {
            title: '进行中',
            color: '#FF6200'
          },
          3: {
            title: '未开始',
            color: '#3291F8'
          },
        }
      }
    }
  },
  data() {
    return {
      year: '',//年
      month: '',//月
      days: [],//日期
      endTime: null,
      startTime: null,
      monthValue: '',
    }
  },
  methods: {
    changeMonth() {
      const date = this.monthValue && this.monthValue.split('-').map(Number) || []
      if (date.length === 0) {
        return
      }
      this.year = date[0];
      this.month = date[1]
      this.days = [];
      this.pushDays();
    },
    //得到当前年这个月分有多少天
    getDays(Y, M) {
      return new Date(Y, M, 0).getDate();
    },
    //得到当前年,这个月的一号是周几
    getWeek(Y, M) {
      let now = new Date()
      now.setFullYear(this.year)
      now.setMonth(this.month - 1)
      now.setDate(1);
      return now.getDay();
    },
    /**
     * 获取本月日期
     */
    pushDays() {
      //将这个月多少天加入数组days
      for (let i = 1; i <= this.getDays(this.year, this.month); i++) {
        const _day = `${i > 9 ? i : '0' + i}`, _month = `${this.month > 9 ? this.month : '0' + this.month}`,
            date = `${this.year}-${_month}-${_day}`;
        this.days.push({
          day: _day,//
          date,
          planList: this.list.filter(item => item.date === date),
          isCurMonth: true,
          month: _month,
          year: `${this.year}`,
          timestamp: new Date(date).getTime(),//转换时间戳
        })
      }
      this.getLastMonthDays()
      this.getNextMonthDays()
    },
    /**
     * 获取下个月的日期
     */
    getNextMonthDays() {
      const month = this.month < 12 ? this.month + 1 : 1,
          year = this.month < 12 ? this.year : this.year + 1,
          len = 42 - this.getDays(this.year, this.month) - this.getWeek(this.year, this.month)
      //将下个月要显示的天数加入days
      for (let i = 1; i <= len; i++) {
        const _day = `${i > 9 ? i : '0' + i}`, _month = `${month > 9 ? month : '0' + month}`,
            date = `${year}-${_month}-${_day}`;
        this.days.push({
          day: _day,
          date,
          month: _month,
          year: `${year}`,
          planList: this.list.filter(item => item.date === date),
          isNextMonth: true,
          timestamp: new Date(date).getTime()
        })
      }
    },
    /**
     * 获取上个月的日期
     */
    getLastMonthDays() {
      const month = this.month > 1 ? this.month - 1 : this.year > 1970 ? 12 : 1,
          year = this.month > 1 ? this.year : this.year > 1970 ? this.year - 1 : 1970,
          len = this.getWeek(this.year, this.month),
          lastMonthDays = this.getDays(this.year, this.month - 1)
      //将上个月要显示的天数加入days
      for (let i = 0; i < len; i++) {
        const _month = month > 9 ? `${month}` : `0${month}`,
            date = `${year}-${_month}-${lastMonthDays - i}`;
        this.days.unshift({
          day: `${lastMonthDays - i}`,
          date,
          month: _month,
          year: `${year}`,
          planList: this.list.filter(item => item.date === date),
          isLastMonth: true,
          timestamp: new Date(date).getTime(),
        })
      }
    },
    /**
     * 获取日期数据
     */
    getDate() {
      let now = new Date();
      this.year = now.getFullYear();
      this.month = now.getMonth() + 1;
      this.pushDays();
    },
    /**
     * 下个月
     */
    handleShowNextMonth() {
      if (this.month < 12) {
        this.month = this.month + 1;
      } else {
        this.month = this.month = 1;
        this.year = this.year + 1;

css部分

<style>
ul {
  list-style: none;
}
.month-container {
  width: 100%;
  border: 1px solid #ddd;
  padding: 20px;
  box-sizing: border-box;
}

.month-top {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1% 0;
  box-sizing: border-box;

}

.month-top .m-btn-wrap {
  width: 200px;
  display: flex;
  justify-content: space-around;
  color: #409EFF;

}

.month-top .m-btn-wrap > span {
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 15px;

}

.month-top .m-card-status {
  display: flex;
  width: 20%;
  justify-content: flex-end;
}

.month-top .m-card-status > div {
  flex: 1;
  display: flex;
  padding: 0 2%;
  white-space: nowrap;
  line-height: 20px;
  box-sizing: border-box;

}

.month-top .m-card-status > div .square {
  display: flex;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  box-sizing: border-box;
}

.month-top .m-card-status > div .title {
  display: flex;
  align-items: center;
  line-height: 16px;
  margin-left: 4px;
  font-size: 14px;
}

.m-date-wrap {
  width: 100%;
  height: auto;

}

.m-date-wrap .m-week {
  width: 100%;
  height: 80px;
  margin: 0;
  line-height: 80px;
  display: flex;
  flex-direction: row;
  font-size: 16px;
  background: #EAEDF2;
  box-sizing: border-box;

}

.m-date-wrap .m-week > li {
  width: 14.28%;
}

.m-date-wrap .m-day {
  width: 100%;
  display: flex;
  flex-direction: row;
  padding: 0;
  margin: 0;
  font-size: 14px;
  flex-wrap: wrap;
  box-sizing: border-box;

}

.m-day .m-date{
  cursor: pointer;
}

.m-date-wrap .m-day > li {
  width: 14.28%;
  padding: 1%;
  min-height: 100px;
  box-sizing: border-box;
  border: 1px solid #ddd;
}

.m-date-wrap .m-day > li .m-card-default {
  cursor: pointer;
  width: 100%;
  min-height: 60px;
  border-radius: 8px;
  display: flex;
  margin: 6% 0;
  flex-direction: column;
  justify-content: space-around;
  white-space: nowrap;
  color: #fff;
  background: #FF6200;
  padding: 2% 4%;
  box-sizing: border-box;
}

.m-date-wrap .m-day > li:nth-child(n+8) {
  border-top: none;
}

.m-date-wrap .m-day > li:nth-child(n+1) {
  border-right: none;
}

.m-date-wrap .m-day > li:nth-child(7n) {
  border-right: 1px solid #ddd
}

.m-isCurMonth {
  background: #fff;
  color: #c0c4cc;
}

.m-isCurToday {
  background: #FFF1F0 10000%;
  color: #FF2525;
}


.m-isActive {
  background: #409EFF;
  color: #f2f8fe;
}

</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue 自定义月日历日程组件(MSchedule) 的相关文章

  • 根据嵌套值使用数组过滤对象数组

    我正在尝试根据某些嵌套对象过滤数组 我准备了一些Fiddle http jsfiddle net NZnN2 249 输入数组如下所示 let arrayOfElements name a subElements surname 1 sur
  • 如何从ArrayBuffer中获取二进制字符串?

    JavaScript中如何从ArrayBuffer中获取二进制字符串 我不想对字节进行编码 只需将二进制表示形式获取为字符串 提前致谢 以下代码将一致地转换ArrayBuffer to a String并再次返回 而不会丢失或添加任何额外的
  • 记录jQuery中调用的方法和参数

    假设我有 jQuery 并且加载了几个插件 我运行一些这样的代码 someSelector someMethod someParam someOtherParam someOtherSelector someOtherMethod anot
  • 为什么“dtoa.c”包含这么多代码?

    我将是第一个承认我对低级编程的整体知识有点稀疏的人 我理解许多核心概念 但我不经常使用它们 话虽这么说 我对需要多少代码感到非常惊讶dtoa c http www netlib org fp dtoa c 在过去的几个月里 我一直致力于用
  • 如何在 JavaScript 中构建一个计算数组中出现次数的对象?

    我想计算数组中某个数字出现的频率 例如 在Python中我可以使用Collections Counter创建一个字典 记录某个项目在列表中出现的频率 据我所知 JavaScript 是这样的 var array 1 4 4 5 5 7 va
  • 使用 ES6 模块导出/导入单个类方法?

    假设我有一个像这样的简单课程fileA js class foo constructor x this name x fooMethod x return x hello 我想导入并使用fooMethod in fileB js像这样 im
  • Relay 中的嵌套片段数据始终相同

    我是 Relay 新手 并且遇到了片段上嵌套数据的问题 当我在 graphiql 中进行测试时 以下查询返回正确的数据 因此我确信我的架构是正确的 viewer customers name billing address city 但是
  • 正则表达式 - 避免表达式中出现字符串

    我正在尝试创建一个应该匹配以下情况的正则表达式 如果单词完全匹配 first second third 那么匹配应该失败 但如果它周围有任何字符 那么应该匹配该字符串 我还需要避免字符串中的某些字符集 如果这些字符是字符串的一部分 则匹配结
  • 用于导出到 CSV/Excel 的数据 URI(无服务器端请求):浏览器支持/限制?

    以下问题 Javascript 或 Flash 导出至 CSV Excel https stackoverflow com questions 8150516 javascript or flash export to csv excel
  • chrome 扩展 - 将数据从后台传递到自定义 html 页面

    创建浏览器扩展 我必须从 background js 打开新选项卡并将 JSON 数据传递到这个新选项卡 在新选项卡中 我使用传递的 JSON 数据来操作 渲染 DOM 下面是我的 background js 的一部分 我在其中使用自定义
  • 如何使用 .append() 将 React 组件附加到 HTML 元素

    我正在尝试对我的博客实现无限滚动 我有 const articlesHTML document querySelector articles 作为容器 每次点击装载更多按钮 我想将新文章附加到主 html 元素 如下所示 const res
  • 在 中动态添加链接样式表 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 如何将链接
  • nvd3.js - 无法更改折线图中线条的颜色

    我正在尝试更改 nvd3 折线图不同线条的颜色here http nvd3 org livecode index html codemirrorNav但我无法理解该怎么做 我想将示例中的 2 条线的颜色更改为绿色和青色 我试过 nv add
  • 使用 dnode 从服务器向客户端发送消息

    几个月前 我发现了 nowjs 和 dnode 并最终使用了 nowjs 并且https github com Flotype nowclient https github com Flotype nowclient 用于客户端 服务器双向
  • 盒式捆绑包与 MVC4 捆绑包

    我目前正在开发一个原型 ASP NET MVC 3 解决方案 该解决方案将用作多个项目重写的基础 来自 Web 表单 我的目标之一是跨应用程序实现一些脚本管理 而不是我们目前没有的目标 MVC 3有一个缺陷恕我直言 如果您需要在部分视图或模
  • 使用 JavaScript 从 URL 变量读取来加载不同的 CSS 样式表

    我试图在我的 WordPress 博客上使用两个不同的样式表 以便在通过 Web 访问页面时使用一个样式表 而在通过我们的 iOS 应用程序访问博客内容时使用另一个样式表 现在 我们将 app true 附加到来自 iOS 应用程序的 UR
  • 地址更改时如何停止 Angular 重新加载

    我正在使用 Angular 的scrollTo and anchorScroll像这样 app controller TestCtrl function scope location anchorScroll scope scrollTo
  • 如何在 jQuery 中检查复选框是否被选中?

    我需要检查checked复选框的属性 并使用 jQuery 根据选中的属性执行操作 例如 如果age复选框被选中 然后我需要显示一个文本框来输入age 否则隐藏文本框 但下面的代码返回false默认情况下 if isAgeSelected
  • 如何仅在第一次访问时弹出模态窗口

    我有一个模式窗口 当您访问某个页面时会弹出 访客必须选择我同意或我不同意 我需要一个漂亮的小 jquery 脚本 它会记住谁之前访问过该页面并同意 这样他们每次访问该页面时就不会弹出模式 有人可以推荐一个好的脚本来使用吗 这是代码 div
  • 使用 stopPropagation() 处理 React 事件委托

    我有一个 React 项目 应该可以放置在任何网站上 我的想法是 我托管一个 javascript 文件 人们放置一个具有特定 ID 的 div 然后 React 在该 div 中进行渲染 到目前为止 除了点击事件之外 这是有效的 这些事件

随机推荐

  • 编译 openwrt 最新实战详细教程

    网上找了很多相关的教程 有些教程太旧了 很多地方都有坑 本人根据一些相关的教程 做了一次实战对比 弥补相关的坑 从源代码构建固件 本节介绍如何从源代码为MTK 7688开发板构建固件 环境 在Ubuntu LTS 14 04 3环境下执行以
  • fd手机抓包

    fd手机抓包问题 大神指点下 欢迎使用Markdown编辑器 你好 这是你第一次使用 Markdown编辑器 所展示的欢迎页 如果你想学习如何使用Markdown编辑器 可以仔细阅读这篇文章 了解一下Markdown的基本语法知识 新的改变
  • TOMCAT-无法成功启动——双击startup.bat闪退的解决办法

    Tomcat无法成功启动 双击startup bat闪退的解决办法 转载 原文链接 https blog csdn net scau lth article details 83218335 这是新手经常会犯的错误 只要注意三个点就可以解决
  • 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。

    开发一个坐标计算工具 A表示向左移动 D表示向右移动 W表示向上移动 S表示向下移动 从 0 0 点开始移动 从输入字符串里面读取一些坐标 并将最终输入结果输出到输出文件里面 输入 合法坐标为A 或者D或者W或者S 数字 两位以内 坐标之间
  • Qt使用帮助文档Assistant

    我们在学习Qt的时候 遇到不懂的地方 可以求助互联网 看教程书籍 也可以直接看Qt的帮助文档Assistant Qt自带的帮助文档是Assistant软件 这可以从Qt的安装路径中找到 我的电脑里Qt的安装路径是E Qt Qt5 14 2
  • Endnote20 在word里插入参考文献 [快捷键Alt+2]

    https www yuque com duzh929 blog kq5u0u原文地址 墙裂建议看看新方法 更简单的新方法 有效解决Endnote20插入参考文献 Endnote20已经上线了 楼主迫不及待的用上了 发现EndnoteX9里
  • MYSQL注入 基础篇1.0

    就算命运不公 重重阻碍 但我在哪里跌倒就一定会在哪里爬起来 只要坚持不懈 那些嘲笑我的人迟早会被我笑死 SQL注入了解 SQL注入是什么 正常的Web端口访问 SQL注入是如何访问 为什么要深入了解SQL注入 SQL注入漏洞的根本原因 SQ
  • 【华为OD机试真题 python】密室逃生游戏【2022 Q4

    题目描述 密室逃生游戏 小强增在参加 密室逃生 游戏 当前关卡要求找到符合给定 密码K 升序的不重复小写字母组成 的箱子 并给出箱子编号 箱子编号为 1 N 每个箱子中都有一个 字符串s 字符串由大写字母 小写字母 数字 标点符号 空格组成
  • JS中的逻辑与和逻辑或

    JS中的逻辑或 符号 从字面上来说 只有前后都是 false 的时候才返回 false 否则返回 true console log 5 gt 6 6 gt 5 返回true 5 gt 6为false 但是 6 gt 5为true 所以返回
  • python-selenium页面定位不到元素

    1 查看是否有新的url打开 当前页面 mainHandle driver current window handle 获取所有的handle Handles driver window handles 循环遍历 找到不是当前页面的就切换
  • vue获取元素offsetTop,mounted获取不到offsetTop,获取元素距离页面顶边距离

    记录一下开发过程中遇到的坑 今天想做一个功能 当我评论完之后 页面跳到评论区顶部 于是就要获取到评论区距离页面顶部的距离 需要循环获取offsetTop来实现 但是在mounted阶段是无论如何都获取不到offsetParent的 不管是
  • C# 对数据库操作的函数总结

    SqlCommand ExecuteNonQuery 方法对连接执行 Transact SQL 语句并返回受影响的行数 可以写也可以读 1 可以使用ExecuteNonQuery 来执行目录操作 例如查询数据库的结构或创建诸如表等的数据库对
  • Unet 语义分割模型(Keras)

    文章目录 前言 一 什么是语义分割 二 Unet 1 基本原理 2 mini unet 3 Mobilenet unet 4 数据加载部分 参考 前言 最近由于在寻找方向上迷失自我 准备了解更多的计算机视觉任务重的模型 看到语义分割任务重U
  • BAT文件里注释符号

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在BAT文件批处理中注释的方式如下 1 注释内容 第一个冒号后也可以跟任何一个非字母数字的字符 2 rem 注释内容 不能出现重定向符号和管道符号 3 echo 注释内容
  • nginx配置https访问

    01 http https HTTP HyperText Transfer Protocol 超文本传输协议 是一种用于分布式 协作式和超媒体信息系统的应用层协议 简单来说就是一种发布和接收 HTML 页面的方法 被用于在 Web 浏览器和
  • 在ubuntu上安装splint

    lint lint是最著名的C语言工具之一 是由贝尔实验室SteveJohnson于1979在PCC PortableC Compiler 基础上开发的静态代码分析 一般由UNIX系统提供 工具介绍 与大多数C语言编译器相比 lint可以对
  • 试图理解 Decagon(二)具体方法

    4 图卷积 Deacgon 方法 综述 关系被表示为一个图 G V R 其中 节点N 蛋白质 药物 vi V 和标记的边 vi r vj r代表边的类型 分别由 蛋白质间的作用 某种药物 与其作用蛋白质间的关系 存在于某两种药物间的副作用关
  • SQLSERVER登录与JDBC连接事宜

    这半天都在帮副主席搞这个 比较最重要的两个点 SQLServer创建用户登录 https www cnblogs com vuenote p 10143434 html 使用JDBC连接SQLSERVER数据库 https www cnbl
  • C51单片机期末复习第八章单片机接口技术

    一 总线 传送同类信息的连线 三总线 地址总线AB 数据总线DB 控制总线CB 目录 ppt给的没啥用 乱还不全 8 1 单片机的系统总线 8 2 简单并行I O口扩展 8 3 可编程并行I O口扩展 8 4 D A转换与DAC0832应用
  • vue 自定义月日历日程组件(MSchedule)

    效果图 组件的使用 日程内容可以自定义 状态对应颜色可以自定义