uni-app实现可选择日期、范围、打点的月份日历

2024-03-06 14:30

本文主要是介绍uni-app实现可选择日期、范围、打点的月份日历,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考插件市场lx-calendar插件:

地址:lx-calendar原插件地址

整体说明

1、始终标记每个月和今天相同的日期,为淡蓝色
2、月份切换为滑动切换
3、可以进行下方打点标记
4、选择日期(日期日期为多选,因功能需要不可选择今天、今天之前、非本月的日期)
(1)单击即可选中日期,选中后为深蓝色
(2)长按日期即可开启范围选择,选中范围开始日期,然后单击范围结束日期,即可选中范围,选完范围后,范围选择关闭
(3)已经选中的日期,单击可取消选中
(4)有选中日期时会出现取消选中按钮,点击即可取消所有选中日期
5、作为组件可以接收两个参数

参数作用类型示例
dot_lists打点标记数组数组[‘2022-12-09’, ‘2022-12-10’, ‘2022-12-11’]
select_lists选中的日期数组[‘2022-12-14’, ‘2022-12-15’, ‘2022-12-16’, ‘2022-12-17’, ‘2022-12-22’, ‘2022-12-27’]

6、显示效果

7、完整代码,使用的是uView的,需要重新找

<template><view class="page"><view class="card"><view class="head"><u-icon name="arrow-left"></u-icon><view class="title">{{nowYear+'年'+nowMonth+'月'}}</view><u-icon name="arrow-right"></u-icon><u-button v-show="select_list.length" @tap="cancel_select" class="cancel-btn" size="mini" type="primary">取消选择</u-button></view><view class="date_week" ><view class="week_td" v-for="(item,index) in week" :key="index">{{item}}</view></view><swiper :style="{height: '480rpx'}" :current="current" circular @change="change_date"><swiper-item><view class="date_week"><view class="week_td" :class="select_list.includes(vo.date) && vo.type == 'month' ? 'select' : ''" @tap="select(vo, index, week_list_prev)" @longtap="selectMore(vo, index)" v-for="(vo,index) in week_list_prev" :key="index"><view class="num" :class="[vo.today && vo.type == 'month' ? 'today': '',vo.type == 'month' ? 'month' : 'disabled']">{{vo.day}}</view><view v-show="vo.dot && vo.type == 'month'" class="dot"></view></view></view></swiper-item><swiper-item><view class="date_week"><view class="week_td" :class="select_list.includes(vo.date) && vo.type == 'month' ? 'select' : ''" @tap="select(vo, index, week_list)" @longtap="selectMore(vo, index)" v-for="(vo,index) in week_list" :key="index"><view class="num" :class="[vo.today && vo.type == 'month' ? 'today': '',vo.type == 'month' ? 'month' : 'disabled']">{{vo.day}}</view><view v-show="vo.dot && vo.type == 'month'" class="dot"></view></view></view></swiper-item><swiper-item><view class="date_week"><view class="week_td" :class="select_list.includes(vo.date) && vo.type == 'month' ? 'select' : ''" @tap="select(vo, index, week_list_next)" @longtap="selectMore(vo, index)" v-for="(vo,index) in week_list_next" :key="index"><view class="num" :class="[vo.today && vo.type == 'month' ? 'today': '',vo.type == 'month' ? 'month' : 'disabled']">{{vo.day}}</view><view v-show="vo.dot && vo.type == 'month'" class="dot"></view></view></view></swiper-item></swiper></view></view>
</template><script>export default {props:{select_lists:{type:Array,default:()=>['2022-12-14', '2022-12-15', '2022-12-16', '2022-12-17', '2022-12-22', '2022-12-27']},dot_lists:{type:Array,default:()=>['2022-12-09', '2022-12-10', '2022-12-11']}},data() {return {week:['日','一','二','三','四','五','六'],week_list: [],week_list_prev: [],week_list_next: [],start_date: '', // 当月的第一天end_date: '', // 当月的最后一天prev_date: '',next_date: '',nowYear: '2022',nowMonth: '12',nowDay: '08',nowTime: 0,current: 1,dot_list:[], // 打点的数组select_list: [],isMore: false,startMore: ''}},watch: {dot_lists:{immediate:true,handler(value){this.dot_list = value;this.set_doc_lists_update()}},select_lists:{immediate:true,handler(value){this.select_list = value;}}},created() {this.init();},methods: {init() {this.get_date();this.doc_list_update();this.update_month();},// 将YYYY-MM-DD变成时间戳date_parse(str){return Date.parse(str.replace(/-(\d)(?!\d)/g, '-0$1'));},select(item, index, list) {if (new Date(item.date).getTime() > new Date().getTime()) {if (item.type == 'month') {if (this.isMore) {var start = Math.min(index, this.startMore);var end = Math.max(index, this.startMore);for (var i = start + 1; i <= end; i++) {this.select_list.push(list[i].date)}this.select_list = [...new Set(this.select_list)]this.isMore = false;return}var index = this.select_list.findIndex(i => i == item.date)if (index > -1) {this.select_list.splice(index, 1)return}this.select_list.push(item.date)} else {uni.showToast({title: '只能操作本月日期~',duration: 3000,icon: 'none'});}return}uni.showToast({title: '只能操作今日之后的日期~',duration: 3000,icon: 'none'});},selectMore(item, index) {if (new Date(item.date).getTime() > new Date().getTime()) {if (item.type == 'month') {this.isMore = true;this.startMore = index;this.select_list.push(item.date)} else {uni.showToast({title: '只能在本月选择日期~',duration: 3000,icon: 'none'});}return}uni.showToast({title: '只能为今日之后的日期添加计划~',duration: 3000,icon: 'none'});},cancel_select() {this.select_list = [];this.isMore = false;this.startMore = '';},// 获得三个月的周列表get_date(value = '', type = 'same') {let date = new Date();if(value){date = new Date(value);}let nowMonth = date.getMonth() + 1,nowYear = date.getFullYear(),nowDay = date.getDate(),nowTime = date.getTime(),nowWeek = date.getDay();// 当前月有多少天let days = this.get_month_days(nowMonth,nowYear);let start_date = new Date(nowYear,nowMonth - 1, 1); // 当月的第一天let end_date = new Date(nowYear,nowMonth - 1, days); // 当月的最后一天let prev_date = new Date(start_date.getTime() - 1); // 要显示的上月的最后一天let prev_date_days = prev_date.getDate(); // 要显示的上月的最后一天的日let next_date = new Date(end_date.getTime() + 86401 * 1000); // 要显示的下月的第一天let next_date_days = next_date.getDate(); // 要显示的下月的第一天的日let start_week = start_date.getDay(); // 当月的第一天是星期几let date_arrs = [];let week_list = []; // 星期数组,一个月贡献是5周let count_days = 42; // 一页显示的天数// 将要显示的上个月的日期纳入日期数组for(let i = prev_date_days - start_week + 1; i <= prev_date_days; i++){date_arrs.push({day:i,type:'prev',today: i == new Date().getDate() ? true : false,date:`${prev_date.getFullYear()}-${prev_date.getMonth()+1 > 9 ? prev_date.getMonth()+1 : '0' + (prev_date.getMonth()+1)}-${i > 9 ? i : '0' + i}`})}// 将要显示的当月日期添加到日期数组for(let i = 1; i <= days; i++){date_arrs.push({day:i,type:'month',today: i == new Date().getDate() ? true : false,date:`${nowYear}-${nowMonth > 9 ? nowMonth : '0' + nowMonth}-${i > 9 ? i : '0' + i}`})}let date_arrs_length = date_arrs.length;// 将要显示的下个月的日期添加到日期数组中for(let i = 1; i <= count_days - date_arrs_length; i++){date_arrs.push({day:i,type:'next',today: i == new Date().getDate() ? true : false,date:`${next_date.getFullYear()}-${next_date.getMonth()+1 > 9 ? next_date.getMonth()+1 : '0' + (next_date.getMonth()+1)}-${i > 9 ? i : '0' + i}`})}// 将当月显示的42天划分为6周的周数组// for(let i = 0; i < date_arrs.length / 7; i++){// 	let arr = [];// 	for(let j = 0; j < 7; j++){// 		arr.push(date_arrs[i * 7 + j]);// 	}// 	week_list.push(arr);// }if(type == 'same'){this.week_list = date_arrs;this.nowYear = nowYear;this.nowMonth = nowMonth;this.nowDay = nowDay;this.nowTime = nowTime;this.start_date = start_date;this.end_date = end_date;this.prev_date = prev_date;this.next_date = next_date;}else if(type == 'prev'){this.week_list_prev = date_arrs;}else if(type == 'next'){this.week_list_next = date_arrs;}},// 获得当月的天数get_month_days(nowMonth,nowYear){let month_arr = [1,3,5,7,8,10,12];let days = 0;if(nowMonth == 2){if(nowYear % 4 == 0){days = 29;}else{days = 28;}}else if(month_arr.indexOf(nowMonth) >= 0){days = 31;}else{days = 30;}return days;},// 获得前一个月和后一个月要显示的日期update_month(){this.get_date(this.get_month('prev'),'prev');this.get_date(this.get_month('next'),'next');},get_month(type){let nowMonth = this.nowMonth;let nowYear = this.nowYear;let nowDay = new Date().getDate();if(type == 'prev'){if(nowMonth == 1){nowMonth = 12;nowYear = Number(nowYear) - 1;}else{nowMonth--;}}else if(type == 'next'){if(nowMonth == 12){nowMonth = 1;nowYear = Number(nowYear) + 1;}else{nowMonth++;}}return this.date_parse(`${nowYear}-${nowMonth}-${nowDay}`);},// 滑动切换获得天数change_date_month(type){let week_list = this.week_list;if(type == 'prev'){this.week_list = this.week_list_prevthis.week_list_prev = this.week_list_next;this.week_list_next = week_list;}else if(type == 'next'){this.week_list = this.week_list_nextthis.week_list_next = this.week_list_prev;this.week_list_prev = week_list;}},// 滑动切换change_date(e){let primary_current = this.current; // 之前显示的swiper-itemlet current = e.detail.current; // 切换后的swiper-itemthis.current = current; // 更新swiper-item的显示if(primary_current - current == -1 || primary_current - current == 2){this.get_date(this.get_month('next'));this.update_month();if(primary_current - current == -1 && current != 1){this.change_date_month('prev')}else if(primary_current - current == 2){this.change_date_month('next')}}else{this.get_date(this.get_month('prev'));this.update_month();if(primary_current - current == 1 && current != 1){this.change_date_month('next')}else if(primary_current - current == -2){this.change_date_month('prev')}}this.set_doc_lists_update();},// 设置打点set_doc_lists_update(){this.doc_list_update('week_list');this.doc_list_update('week_list_prev');this.doc_list_update('week_list_next');},// 为当前月设置打点doc_list_update(week_list = 'week_list'){let list = [];// item为一周的数组this[week_list].forEach((vo,key)=>{// vo为一天的对象if(this.dot_list.indexOf(vo.date) > -1 || this.dot_list.indexOf(vo.date.replace(/-(\d)(?!\d)/g, '-0$1')) > -1 ){vo.dot = true;}else{vo.dot = false;}list.push(vo)})this[week_list] = list;},}}
</script><style lang="scss">@import '@/uview-ui/index.scss';.page {width: 100vw;height: 100vh;background: #F1F1F1;box-sizing: border-box;padding-top: 10rpx;}.card {width: 720rpx;margin: 10rpx auto;padding: 10rpx;box-sizing: border-box;background: #fff;border-radius: 10rpx;box-shadow: 0 0 10rpx #C0C0C0;.head {position: relative;height: 80rpx;display: flex; justify-content: center;align-items: center;font-size: 36rpx;color: #333;padding: 15rpx 0;.title {margin: 0 15rpx;}.cancel-btn {position: absolute;right: 20rpx;}}.date_week {display: flex;justify-content: center;flex-wrap: wrap;width: 100%;height: 100%;.week_td {width: 101rpx;height: 70rpx;font-size: 30rpx;display: flex;flex-direction: column;justify-content: center;align-items: center;&.select{background: #007aff;.num {color: #fff!important;}}.num {width: 60rpx;height: 60rpx;border-radius: 50%;line-height: 60rpx;text-align: center;&.disabled{color: #ccc;}&.month{color: #333;}&.today{background: #94adff; color:#fff;}}.dot {margin-top: 5rpx;width: 8rpx;height: 8rpx;border-radius: 50%;background: #007aff; }}}}
</style>

这篇关于uni-app实现可选择日期、范围、打点的月份日历的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/780352

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S