uniapp----微信小程序 日历组件(周日历 月日历)【Vue3+ts+uView】

uniapp----微信小程序 日历组件(周日历&& 月日历)【Vue3+ts+uView】

  1. 用Vue3+ts+uView来编写日历组件;
  2. 存在周日历和月日历两种显示方式;
  3. 高亮显示当天日期,红点渲染有数据的日期,点击显示数据

1. calendar-week-mouth组件代码

<template><view class="calender-container"><view class="calender-content"><!-- 头部 --><view class="calender-title" v-if="isWeek"><view class="calender-title-left">{{ checkedDay }}</view><view class="calender-title-morebtn" v-if="isMorebtn" @click="toggleMove">更多</view><view class="calender-title-right" @click="popupShowBtn" v-if="ispopupShow"></view></view><view class="calender-title" v-if="!isWeek"><view class="calender-title-chevronl" @click="changeMonth(-1)"><text class="iconfont icon-back text-[28rpx]"></text></view><view class="calender-title-mouth">{{ MoutnTitle }}</view><view class="calender-title-chevronr calender-title-chevronr-right"><text class="iconfont icon-right text-[28rpx]" @click="changeMonth(1)"></text></view></view><!-- 星期头部 --><view class="calender-week-head"><view class="calender-week-head-item" v-for="(item, index) in WEEK_LIST" :key="index">{{ item.text }}</view></view><transition name="fade"><view class="calender-month-container" :class="{ transition: transition }" :style="{height: isWeek ? '120rpx' : '540rpx'}"><view v-for="(month, index) in monthList" :key="index" class="calender-month-item"><view v-for="(week, weekindex) in month" :key="weekindex" class="calender-month-week"><!--   :class="{ ischecked: checkedDay == day.date, istoday: day.istoday }" --><view v-for="(day, dayindex) in week" :class="{ ischecked: checkedDay == day.date }"@click.stop="chooseDay(day)" :key="dayindex" class="calender-month-week-item"><view class="calender-week-day" :class="{ischecked: checkedDay == day.date,othermonth: day.othermonth}"><span class="calender-one-day"><i class="day">{{day.othermonth === -1 || day.othermonth === 1? '': day.day}}</i></span><!-- 有事项标记 --><view class="thing" v-if="day.thing.task_time != null"><i class="dot"></i></view></view></view></view></view></view></transition></view><slot></slot></view><!-- 日历问号提示弹出框 --><w-calender-popup :popupShow="popupShow"></w-calender-popup>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, nextTick } from 'vue'const props = withDefaults(defineProps<{isWeek: booleanthings: Array<any> //日期对应的相关数据 数据格式 一维数组ispopupShow: booleanisMorebtn: boolean}>(),{isWeek: true, // true周 false 月ispopupShow: true, // 是否显示?问号弹窗 默认显示isMorebtn: false //是否显示日历更多按钮 默认不显示}
)const emits = defineEmits(['chooseDay', 'toggleMove']) //组件传递数据
const popupShow = ref<boolean>(false) //是否显示日历问号提示
// 打开提示框
const popupShowBtn = () => {popupShow.value = !popupShow.value
}// 头部星期列表
const WEEK_LIST = [{text: '日'},{text: '一'},{text: '二'},{text: '三'},{text: '四'},{text: '五'},{text: '六'}
]
const dateThing: any = ref([]) //某天事项// const things: any = ref([]) // 全部事项,用来插入到日历中
const dispDate = ref<Date>(new Date()) //当前时间type DayType = {date?: string | numberistoday?: booleanothermonth?: booleanthing?: []
}
type MonthList = DayType[]
const monthList: Record<string, any> = ref<MonthList>([])
const today = ref<Date>(new Date()) //当前时间
const MoutnTitle = ref('') //当前月份 x-x格式
const checkedDay = ref('') //选中时间
const currentDay = ref<Date>(new Date()) //当前时间
const transition = ref<boolean>(true) //是否显示动画const get3FullYear = ref(dispDate.value.getFullYear()) //定义当前年
const get3Monthz = ref(dispDate.value.getMonth()) //定义当前月
onMounted(() => {setTimeout(() => {todayDate()props.isWeek ? get3week() : get3month(get3FullYear.value, get3Monthz.value)initCalenderInfo()}, 200)
})
watch(() => props.things,async () => {await nextTick()todayDate()props.isWeek ? get3week() : get3month(get3FullYear.value, get3Monthz.value)initCalenderInfo()},{ immediate: true }
)
const selectDay = ref<Date>(new Date())
/*** 转换时间格式* @param date 标准时间*/
const formatDateTime = (date: Date): string => {const y = date.getFullYear()let m: string = date.getMonth() + 1 + ''m = Number(m) < 10 ? '0' + m : mlet d = date.getDate() + ''d = Number(d) < 10 ? '0' + d : dreturn y + '-' + m + '-' + d
}/*** 获取今天日期*/
const todayDate = () => {checkedDay.value = formatDateTime(today.value)selectDay.value = new Date(checkedDay.value)MoutnTitle.value = formatDateTime(today.value).substring(0, 7)
}
/*** 初始化当天事项*/
const initCalenderInfo = () => {const todayThing = monthList.value.flat(2).find((item: any) => item.date === checkedDay.value)?.thingdateThing.value = todayThing || []
}
/*** 返回该天事项* @param year 年* @param month 月* @param day 日*/
const ifOrder = (year: number, month: number, day: number) => {const dateTime = format(year, month, day)let dateItem = {}props.things.map((item: any) => {if (dateTime === item.task_time) {dateItem = item}})return dateItem
}/*** 转换时间* @param year 年* @param month 月* @param day 日*/
const format = (year: number, month: number, day: number | string) => {month++const m = month < 10 ? '0' + month : monthNumber(day) < 10 && (day = '0' + day)return year + '-' + m + '-' + day
}/*** 选中某一天* @param year 年* @param month 月* @param day 日* @param othermonth 其他月份,当前月前面空值* @param mode 类型,'month','week'* @param thing 事项*/
interface chooseDayParams {year: numbermonth: numberday: numberothermonth: numbermode: stringthing: Thing[]
}interface Thing {date: stringinfos?: ThingInfo[]
}interface ThingInfo {title: stringaddress: stringdates: string
}/*** @description: 选中日期* @param {*} year* @param {*} month* @param {*} day* @param {*} othermonth* @param {*} mode* @param {*} thing* @return {*}*/
const chooseDay = ({ year, month, day, othermonth, mode, thing }: chooseDayParams): void => {currentDay.value = new Date(year, month - 1, day) //标准时间checkedDay.value = format(year, month - 1, day) //"2020-11-11"if (othermonth && mode === 'month') {const tmpDt = new Date(dispDate.value.getFullYear(), dispDate.value.getMonth() - othermonth)const maxday = tmpDt.getDate()const days = maxday < day ? maxday : daydispDate.value = new Date(year, month - othermonth, days)changeIndex(othermonth || 0, true)} else {dispDate.value = currentDay.value}dateThing.value = thing || []emits('chooseDay', checkedDay.value)
}/*** 获取三周*/
const get3week = () => {const year = dispDate.value.getFullYear()const month = dispDate.value.getMonth()const day = dispDate.value.getDate()monthList.value = []monthList.value.push(getWeek(year, month, day - 7))monthList.value.push(getWeek(year, month, day))monthList.value.push(getWeek(year, month, day + 7))
}/*** 获取星期* @param year 为选中当天的年* @param month 为选中当天的月* @param day 为选中当天的日*/
const getWeek = (year: number, month: number, day: number) => {const dt = new Date(year, month, day)const weekArr = []const dtFirst = new Date(year, month, day - ((dt.getDay() + 7) % 7))const week = []//循环选中当天所在那一周的每一天for (let j = 0; j < 7; j++) {const newdt = new Date(dtFirst.getFullYear(), dtFirst.getMonth(), dtFirst.getDate() + j)const years = newdt.getFullYear()const months = newdt.getMonth()const days = newdt.getDate()const weekItem: weekParams = {mode: 'week',day: days,year: years,month: months + 1,date: format(years, months, days),//日历要显示的其他内容thing: ifOrder(years, months, days),istoday:today.value.getFullYear() === years &&today.value.getMonth() === months &&today.value.getDate() === days? true: false,ischecked: false,othermonth: months !== month}week.push(weekItem)}weekArr.push(week)return weekArr
}/*** 获取三个月(上月,本月,下月)*/
const get3month = (year: any, month: any) => {monthList.value = []monthList.value.push(getMonth(year, month - 1))monthList.value.push(getMonth(year, month))monthList.value.push(getMonth(year, month + 1))
}
const MonthType = ref(0) //0 当前月 -1上一个月 1下一个月
let Mnum = 1 //计数
let Ynum = 0// 点击上一个月 或者下一个月
const changeMonth = (type: number) => {MonthType.value = typeconst date = new Date()const year = date.getFullYear()const month = date.getMonth()let nextYear = year - Ynumlet chMonth = month + Mnumif (type === -1) {// 上一个月Mnum -= 1chMonth = month + MnumYnum = chMonth <= 0 ? Ynum - 1 : YnumchMonth = chMonth <= 0 ? 12 + chMonth : chMonth}if (type === 1) {// 下一个月Mnum += 1chMonth = month + MnumYnum = chMonth > 12 ? Ynum + 1 : YnumchMonth = chMonth > 12 ? chMonth - 12 : chMonth}nextYear = year + Ynumget3FullYear.value = nextYear //修改当前年get3Monthz.value = chMonth - 1 //修改当前月get3month(get3FullYear.value, get3Monthz.value)const newMonthTitle = `${nextYear}-${chMonth < 10 ? '0' + chMonth : chMonth}`MoutnTitle.value = newMonthTitle
}interface weekParams {mode: stringday: numberyear: numbermonth: numberdate: string//日历要显示的其他内容thing: ReturnType<typeof ifOrder>istoday: booleanischecked: booleanothermonth?: number | boolean
}/*** 创建单月历 顺序是从周日到周六* @param year 年* @param month 月*/
const getMonth = (year: number, month: number): DayType => {const monthArr = [] as anyconst dtFirst = new Date(year, month, 1) // 每个月第一天const dtLast = new Date(year, month + 1, 0) // 每个月最后一天const monthLength = dtLast.getDate() // 月份天数const firstDayOfWeek = dtFirst.getDay() // 第一天是星期几const rows = Math.ceil((monthLength + firstDayOfWeek) / 7) // 表格显示行数for (let i = 0; i < rows; i++) {const week = []for (let j = 0; j < 7; j++) {const day = i * 7 + j + 1 - firstDayOfWeekif (day > 0 && day <= monthLength) {const weekItem: weekParams = {mode: 'month',day: day,year: year,month: month + 1,date: format(year, month, day),// 日历要显示的其他内容thing: ifOrder(year, month, day),istoday:today.value.getFullYear() === year &&today.value.getMonth() === month &&today.value.getDate() === day? true: false,ischecked: false,othermonth: 0}week.push(weekItem)} else {// 其它月份const newDt = new Date(year, month, day)const years = newDt.getFullYear()const months = newDt.getMonth()const days = newDt.getDate()const weeksItem: weekParams = {mode: 'month',day: days,year: years,month: months,date: format(year, month, day),thing: ifOrder(year, month, day),istoday:today.value.getFullYear() === years &&today.value.getMonth() === months &&today.value.getDate() === days? true: false,ischecked: false,othermonth: day <= 0 ? -1 : 1}week.push(weeksItem)}}monthArr.push(week)}return monthArr
}
/*** 左右移动* @param index 月的index* @param isWeek 是否显示周* @param isClick 移动不可点击*/
const changeIndex = (index: number, isClick = false) => {if (props.isWeek) {dispDate.value = new Date(dispDate.value.getFullYear(),dispDate.value.getMonth(),dispDate.value.getDate() + 7 * index)currentDay.value = dispDate.valueget3week()} else {const tmpDt = new Date(dispDate.value.getFullYear(), dispDate.value.getMonth() + index, 0)const maxday = tmpDt.getDate()const days = maxday < dispDate.value.getDate() ? maxday : dispDate.value.getDate()dispDate.value = new Date(dispDate.value.getFullYear(),dispDate.value.getMonth() + index,days)if (!isClick) {checkedDay.value = format(dispDate.value.getFullYear(),dispDate.value.getMonth(),dispDate.value.getDate())}get3month(get3FullYear.value, get3Monthz.value)}initCalenderInfo()
}/*** 切换月或周* @param e event*/
const toggleMove = () => {emits('toggleMove')
}
</script>
<style scoped lang="scss">
.calender {&-container {width: 100%;}&-content {color: #666666;}&-title {display: flex;&-left {width: 70%;}&-right {position: absolute;right: 60rpx;width: 50rpx;height: 50rpx;border: 1px solid #e51c15;color: #e51c15;line-height: 44rpx;text-align: center;border-radius: 50%;font-size: 32rpx;padding-left: 14rpx;}&-morebtn {border: 2rpx solid #e51c15;// padding: 10rpx 40rpx;width: 120rpx;height: 46rpx;line-height: 46rpx;text-align: center;color: #e51c15;box-sizing: border-box;font-size: 24rpx;margin-right: 20rpx;border-radius: 10rpx;}&-chevronl text,&-chevronr text {color: #e51c15;font-size: 28rpx;font-weight: 400;&-right {text-align: right;}}&-mouth {width: 92%;text-align: center;font-size: 32rpx;color: #666666;}}&-week-head {width: 100%;display: flex;align-items: center;padding-top: 20px;font-size: 24rpx;font-weight: bold;&-item {// width: 14.2%;flex: 1;text-align: center;}}&-month {&-container {display: flex;position: relative;height: 460rpx;}&-item {position: absolute;width: 100%;min-height: 128rpx;padding: 30rpx 0;box-sizing: border-box;}&-item:nth-child(1) {left: -110%;}&-item:nth-child(2) {left: 0;}&-item:nth-child(3) {left: 110%;}&-week {display: flex;align-items: center;&-item {// width: 14.2%;flex: 1;text-align: center;position: relative;}}}&-week-day {display: block;text-align: center;font-style: normal;padding: 2rpx;line-height: 60rpx;height: 80rpx;width: 80rpx;}&-one-day {font-size: 24rpx;}
}.istoday .day,
.ischecked .day {width: 60rpx;height: 60rpx;color: #fff;background: #e51c15;border-radius: 50%;line-height: 60rpx;text-align: center;
}// .ischecked {
//     border-radius: 50px;
//     color: #fff !important;
//     background: #7687e9;
// }
.thing {position: absolute;left: 34%;// bottom: 2px;transform: translateX(-50%);color: #e51c15;
}.thing .dot {display: block;width: 12rpx;height: 12rpx;word-break: break-all;line-height: 12rpx;color: #e51c15;background: #e51c15;border-radius: 50%;margin-top: 6rpx;
}
</style>

2. 在页面引用组件

<template>
<calendar-week-mouth :things="things" @chooseDay.stop="chooseDay" :isMorebtn="true" @toggleMove="toggleMove" ispopupShow :isWeek="isWeek">
</calendar-week-mouth>
</template><script setup lang="ts">
import { ref, watch, nextTick, shallowRef } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
onLoad(async (options) => {tag.value = Number(options.tag) || 1isWeek.value = tag.value === 1 || false
})
const tag = ref(1) //tag 1是周日历显示 2是月日历显示
const isWeek = ref(true)/*** @description: 点击单个日期获取选中的日期* @param {*} date:选中的日期 xxxx-xx-xx* @return {*}*/
const chooseDay = (date: string) => {checkedDay.value = date
}// 点击更多
const toggleMove = () => {uni.navigateTo({ url: '/package-legal/task-list/task-list?tag=2' })
}
/**
things数据结构
重要的是task_time字段
[{
id: 4,
status: 3,
task_time: "2023-07-26",
task_title: "",
time: "222",
}]
*/
</script>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

数据结构——AVL树

目录 1.什么是AVL树&#xff1f; 2.AVL树插入的模拟实现 ①节点定义 ②插入 ③旋转 ⑴右单旋 ⑵左单旋 ⑶双旋&#xff08;右左旋&#xff09; ⑷双旋&#xff08;左右旋&#xff09; ⑸完整的插入代码 3.AVL树的性能分析 1.什么是AVL树&#xff1f; AVL树是一种自…

NLP文本生成全解析:从传统方法到预训练完整介绍

目录 1. 引言1.1 文本生成的定义和作用1.2 自然语言处理技术在文本生成领域的使用 2 传统方法 - 基于统计的方法2.1.1 N-gram模型2.1.2 平滑技术 3. 传统方法 - 基于模板的生成3.1 定义与特点3.2 动态模板 4. 神经网络方法 - 长短时记忆网络(LSTM)LSTM的核心概念PyTorch中的LST…

中尺度混凝土二维有限元求解——运行弯曲、运行光盘、运行比较、运行半圆形(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

YOLOv8快速复现 训练 SCB-Dataset3-S 官网版本 ultralytics

目录 0 相关资料SCB-Dataset3-S 数据训练yaml文件 YOLOv8 训练SCB-Dataset3-S相关参数 0 相关资料 YOLOV8环境安装教程.&#xff1a;https://www.bilibili.com/video/BV1dG4y1c7dH/ YOLOV8保姆级教学视频:https://www.bilibili.com/video/BV1qd4y1L7aX/ b站视频&#xff1a;…

ceph分布式存储

ceph特点 Ceph项目最早起源于Sage就读博士期间的工作&#xff08;最早的成果于2004年发表&#xff09;&#xff0c;并随后贡献给开源社区。在经过了数年的发展之后&#xff0c;目前已得到众多云计算厂商的支持并被广泛应用。RedHat及OpenStack都可与Ceph整合以支持虚拟机镜像的…

经典指标策略回测一览

编辑 经典指标策略回测一览 关键词 A股市场&#xff08;沪深京三市&#xff09; 5000股票20年内日线走势回测&#xff0c;区分除权&#xff0c;前复权&#xff0c;后复权三种模式&#xff1b;由于数据量较大&#xff0c;采用两种方式共享数据&#xff0c;一是 天启网站的数据…

每天几道Java面试题:IO流(第五天)

目录 第五幕 、第一场&#xff09;街边 友情提醒 背面试题很枯燥&#xff0c;加入一些戏剧场景故事人物来加深记忆。PS:点击文章目录可直接跳转到文章指定位置。 第五幕 、 第一场&#xff09;街边 【衣衫褴褛老者&#xff0c;保洁阿姨&#xff0c;面试者老王】 衣衫褴褛老…

【数据结构】二叉树的·深度优先遍历(前中后序遍历)and·广度优先(层序遍历)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

CDH 集群离线部署、大数据组件安装与扩容详细步骤(cdh-6.3.1)

一、环境准备 1、服务器配置和角色规划 IP 地址主机名硬件配置操作系统安装步骤10.168.168.1cm-server8C16GCentos7新建10.168.168.2agent018C16GCentos7新建10.168.168.3agent028C16GCentos7新建10.168.168.4agent038C16GCentos7新建10.168.168.5agent048C16GCentos7扩容 2…

七天学会C语言-第五天(函数)

1. 调用有参函数 有参函数是一种接受输入参数&#xff08;参数值&#xff09;并执行特定操作的函数。通过向函数传递参数&#xff0c;你可以将数据传递给函数&#xff0c;让函数处理这些数据并返回结果。 例1&#xff1a;编写一程序&#xff0c;要求用户输入4 个数字&#xf…

Innodb底层原理与Mysql日志机制

MySQL内部组件结构 Server层 主要包括连接器、词法分析器、优化器、执行器等&#xff0c;涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;&#xff0c;所有跨存储引擎的功能都在这一层实现&#xff0c…

超级详细 SQL 优化大全

1、MySQL的基本架构 1&#xff09;MySQL的基础架构图 左边的client可以看成是客户端&#xff0c;客户端有很多&#xff0c;像我们经常你使用的CMD黑窗口&#xff0c;像我们经常用于学习的WorkBench&#xff0c;像企业经常使用的Navicat工具&#xff0c;它们都是一个客户端。右…

Python实现Redis缓存MySQL数据并支持数据同步

简介 本文讲讲如何用Redis做MySQL的读缓存&#xff0c;提升数据库访问性能。 MySQL是一种很常用的关系型数据库&#xff0c;用于持久化数据&#xff0c;并存放在磁盘上。但如果有大数据量的读写&#xff0c;靠MySQL单点就会捉襟见肘&#xff0c;尽管可以在MySQL本身做优化&am…

Qt httpclient

记录一次Qt中处理https请求的操作 构造函数 get onFinished函数&#xff1a; onCompleted是对外的信号&#xff0c;这里接收的数据主要是文本类 post form post json Form 与 Json的差别是http header 的设置 文件下载处理 这里与服务器有个约定&#xff0c;文件长度不能小于…

springboot整合sentinel完成限流

1、直入正题&#xff0c;下载sentinel的jar包 1.1 直接到Sentinel官网里的releases下即可下载最新版本&#xff0c;Sentinel官方下载地址&#xff0c;直接下载jar包即可。不过慢&#xff0c;可能下载不下来 1.2 可以去gitee去下载jar包 1.3 下载完成后&#xff0c;进行打包…

68、Spring Data JPA 的 方法名关键字查询(全自动,既不需要提供sql语句,也不需要提供方法体)

1、方法名关键字查询&#xff08;全自动&#xff0c;既不需要提供sql语句&#xff0c;也不需要提供方法体&#xff09; 2、Query查询&#xff08;半自动&#xff1a;提供 SQL 或 JPQL 查询&#xff09; 3、自定义查询&#xff08;全手动&#xff09; ★ 方法名关键字查询&…

简明 SQL 组合查询指南:掌握 UNION 实现数据筛选

在SQL中&#xff0c;组合查询是一种将多个SELECT查询结果合并的操作&#xff0c;通常使用UNION和UNION ALL两种方式。 UNION 用于合并多个查询结果集&#xff0c;同时去除重复的行&#xff0c;即只保留一份相同的数据。UNION ALL 也用于合并多个查询结果集&#xff0c;但不去除…

3D模型格式转换工具HOOPS Exchange与iBase-t的Solumina集成:支持用户查询与编辑模型

iBase-t是一家软件公司&#xff0c;致力于简化复杂产品的构建和维护。iBase-t 于 1986 年在南加州成立&#xff0c;提供的解决方案可确保全球范围内制造、质量以及维护、修理和大修 (MRO) 运营的数字连续性。iBase-t 的 Solumina 制造运营平台是一种云原生解决方案&#xff0c;…

PX4 通过 Vision 实现 Position、Altitude 和 Offboard 模式

本文通过 VINS-Fusion 的里程计信息为 PX4 提供视觉信息&#xff0c;从而达到 视觉定高和定点 的目的 主要工作为创建一个将 vins 里程计信息发布给 Mavros 的 /mavros/vision_pose/pose 话题 首先创建一个工作空间 mkdir -p ~/catkin_ws/src/vision_to_mavros/src/ cd ~/ca…

贝叶斯滤波计算4d毫米波聚类目标动静属性

机器人学中有些问题是二值问题&#xff0c;对于这种二值问题的概率评估问题可以用二值贝叶斯滤波器binary Bayes filter来解决的。比如机器人前方有一个门&#xff0c;机器人想判断这个门是开是关。这个二值状态是固定的&#xff0c;并不会随着测量数据变量的改变而改变。就像门…