背景

最近项目中需要使用到日历组件,并且需要在日视图上显示当天的日报数据,最终实现的效果图如下所示:

看起来还是有些丑的,不过在此还是把实现的过程记录一下。

1、需求拆分

从上图来看,我们的界面主要分为三部分,日历周视图、时间侧边栏、右侧日程内容,下面就对这三部分内容分别进行实现。

2、顶部日历周视图

顶部日历周视图采用了自定义组件去实现,以便于后面需要用到它的地方可以进行复用。

2.1 日历周试图的实现

1)在微信开发者工具中创建一个工程,并且在工程中与 pages文件夹同级下,新建一个 component文件夹。

2)在component文件夹下新建  calendarweek文件夹,并且在微信开发者工具右键 点击  calendarweek文件夹, 选择 “新建Component” 输入  "calendarweek"文件名,如下图所示结构:

2.2 calendarweek.js 的实现

// component/calendarweek.js
var utils = require('../../utils/util')
Component({/*** 组件的属性列表*/properties: {setdate: {type: String,value: ''},},/*** 组件的初始数据*/data: {dateList: [], // 日历数据数组swiperCurrent: 0, // 日历轮播正处在哪个索引位置dateCurrent: new Date(), // 正选择的当前日期dateCurrentStr: '', // 正选择日期的 iddateMonth: '1月', // 正显示的月份dateListArray: ['日', '一', '二', '三', '四', '五', '六'],},ready: function () {//获取高度const query = this.createSelectorQuery()query.select('#calendarweekheight').boundingClientRect()query.selectViewport().scrollOffset()query.exec((res)=>{// console.log(res[0].height)let a = res[0].heightthis.triggerEvent('getHeader',a)})var today = utils.formatTime2(new Date());this.setData({today,});//2021-03-19if(this.properties.setdate != ''){let year = this.properties.setdate.substring(0,4);let month = this.properties.setdate.substring(5,7);let day = this.properties.setdate.substring(8);var d = new Date(year,month - 1,day);this.initDate(-5, 2, d); // 日历组件程序  -4左表示过去4周  右1表示过去一周 } else {var d = new Date();this.initDate(-5, 2, d); // 日历组件程序  -4左表示过去4周  右1表示过去一周 }   },/*** 组件的方法列表*/methods: {tiaotime(e) {let data = e.detail.value.split("-")var d = new Date(Number(data[0]), Number(data[1]) - 1, Number(data[2]));this.setData({dateList: []})this.initDate(-5, 2, d); // 日历组件程序  -4左表示过去4周  右1表示过去一周},// 日历组件部分// ----------------------------initDate(left, right, d) {var month = utils.addZero(d.getMonth() + 1),year = utils.addZero(d.getFullYear()),day = utils.addZero(d.getDate());for (var i = left; i <= right; i++) {this.updateDate(utils.DateAddDay(d, i * 7)); //多少天之后的}this.setData({swiperCurrent: 5,dateCurrent: d,dateCurrentStr: d.getFullYear() + '-' + month + '-' + day,dateMonth: month + '月',dateYear: year + '年',dateCurrentStr: year + "-" + month + "-" + day,});},// 获取这周从周日到周六的日期calculateDate(_date) {var first = utils.FirstDayInThisWeek(_date);var d = {'month': first.getMonth() + 1,'days': [],};for (var i = 0; i < 7; i++) {var dd = utils.DateAddDay(first, i);var day = utils.addZero(dd.getDate()),year = utils.addZero(dd.getFullYear()),month = utils.addZero(dd.getMonth() + 1);d.days.push({'day': day,'id': dd.getFullYear() + '-' + month + '-' + day,'ids': dd.getFullYear() + ',' + month + ',' + day,});}return d;},// 更新日期数组数据updateDate(_date) {var week = this.calculateDate(_date);this.setData({dateList: this.data.dateList.concat(week),});},// 日历组件轮播切换dateSwiperChange(e) {const lastIndex = this.data.swiperCurrent,currentIndex = e.detail.current,dateList = this.data.dateListlet flag = false,key = 'lastMonth' //判断是左划还是右 if (lastIndex > currentIndex) {lastIndex === 7 && currentIndex === 0 ?flag = true :null} else {lastIndex === 0 && currentIndex === 7 ?null :flag = true}if (flag) {key = 'nextMonth'}if (key == 'lastMonth') {let nowindex = currentIndex - 3;let uptime = currentIndex - 4;let a = 0;if (nowindex < 0) {nowindex = nowindex + 8;a = 0}if (uptime < 0) {uptime = uptime + 8}let seltime = dateList[nowindex].days[a].ids.split(',')var week = this.calculateDate(utils.formatTime(utils.DateAddDay(new Date(Number(seltime[0]), Number(seltime[1]) - 1, Number(seltime[2])), -1)));dateList[uptime] = weekthis.setData({dateList: dateList})}if (key == 'nextMonth') {let indexne = 0let aa = 0if (currentIndex == 7) { //要更新的下标indexne = 0aa = 1} else {indexne = currentIndex + 1aa = currentIndex + 2}if (aa == 8) {aa = 0}//aa 要更新的数组下标 datanex要往后查询一周的日期let datanex = dateList[indexne].days[6].ids.split(',')//获取下一周的var week = this.calculateDate(utils.formatTime(utils.DateAddDay(new Date(Number(datanex[0]), Number(datanex[1]) - 1, Number(datanex[2])), 1)));dateList[aa] = weekthis.setData({dateList: dateList})}var dDateFormat = this.data.dateList[currentIndex].days[3].ids.split(',');this.setData({swiperCurrent: currentIndex,dateMonth: dDateFormat[1] + '月',dateYear: dDateFormat[0] + "年"})},// 获得日期字符串getDateStr: function (arg) {if (utils.type(arg) == 'array') {return arr[0] + '-' + arr[1] + '-' + arr[2] + ' 00:00:00';} else if (utils.type(arg) == 'date') {return arg.getFullYear() + '-' + (arg.getMonth() + 1) + '-' + arg.getDate() + ' 00:00:00';} else if (utils.type(arg) == 'object') {return arg.year + '-' + arg.month + '-' + arg.day + ' 00:00:00';}},// 点击日历某日chooseDate(e) {var str = e.currentTarget.id;console.log("当前选择的日期:",str);this.setData({dateCurrentStr: str});this.triggerEvent('myevent', {data: str})},}
})

2.3 calendarweek.wxml 的实现

<!--component/calendarweek.wxml-->
<view id="calendarweekheight" class="date-choose shrink border-bottom10"><view class="weekday"><block wx:for-item="weekday" wx:for="{{dateListArray}}" wx:key="{{index}}"><text class="week">{{weekday}}</text></block></view><swiper class="date-choose-swiper" circular="true" indicator-dots="{{false}}" current="{{swiperCurrent}}"bindchange="dateSwiperChange"><block wx:for="{{dateList}}" wx:for-item="date" wx:key="date.id"><swiper-item class="swiper-item"> <view class="dateday"><block wx:for="{{date.days}}" wx:for-item="day" wx:key="{{day.id}}"><view class="day" id="{{day.id}}" bindtap="chooseDate"><text class="{{dateCurrentStr==day.id?'active':'nomal'}}{{today==day.id?' reds':''}}">{{day.day}}</text></view></block></view></swiper-item></block></swiper>
</view>

2.4 、calendarweek.wxss的实现

/* component/calendarweek.wxss */
.date-choose {background: #fff;overflow: hidden;height: auto;
}.data-month {width: 100%;align-items: center;padding: .5rem .35rem;text-align: left;color: #333;font-size: 24rpx;
}.date-choose-swiper {flex-grow: 1;height: 120rpx;
}.swiper-item {display: flex;flex-direction: column;
}.weekday,
.dateday {display: flex;justify-content: space-between;align-items: center;text-align: center;flex-wrap: wrap;flex-grow: 1;
}.week,
.day {width: 14.286%;flex-basis: 14.286%;
}.week {font-size: 20rpx;font-family: PingFang SC;/* font-weight: bold; */color: #000000;
}.day text {position: relative;color: #333333;
}.day .active:before {/* 圈圈 */content: "";position: absolute;width: 55rpx;height: 55rpx;top: 50%;left: 50%;-webkit-transform: translate(-50%, -50%);transform: translate(-50%, -50%);border: 1px solid #286AFE;border-radius: 100%;background-color: #286AFE;/* opacity: 0.8; */z-index: -1;
}.day text.active {color: #ffffff;font-size: 24rpx; font-family: PingFang SC;/* font-weight: bold; */
}.nomal{font-size: 24rpx; font-family: PingFang SC;/* font-weight: bold; */
}.day text.reds {color: #ff0000;font-size: 24rpx;
}/*开始*/.headerone {width: 100%;height: auto;font-size: 24rpx;
}.headerone .ra {margin-right: 20rpx;
}.headerone .radio-group {margin: 20rpx 0 20rpx 30rpx;
}.headertwo {width: 100%;height: auto;font-size: 24rpx;margin-top: 10rpx;margin-bottom: 26rpx;
}.headertwo .le image {width: 70rpx;height: 70rpx;border-radius: 10px;margin-left: 30rpx;margin-right: 20rpx
}.headertwo .ri {flex: 1;margin-right: 30rpx;border-radius: 6px;box-shadow: 0px 1px 6px 0px rgba(198, 198, 198, 0.5);
}.headertwo .ri .one {width: 100%;padding-top: 24rpx;padding-bottom: 24rpx
}.headertwo .ri .one view .jiao {margin: 0 16rpx;border: 15rpx solid; border-color: #ffffff #ffffff #b3b3b3 #ffffff;
}.xi {background: red;color: #ffffff;padding: 3px 10px;border-radius: 6px 0px 0 6px;
}.headertwo .ri .one view view.jiaos {margin: 0 16rpx;border: 15rpx solid;margin-top: 14rpx;border-color: #b3b3b3 #ffffff #ffffff #ffffff;
}.headertwo .ri .two {width: 100%;overflow: hidden;transition: all 0.5s
}.headertwo .ri .two .body {width: 100%;padding-top: 24rpx;padding-bottom: 24rpx;
}

2.5 、util.js 的实现

// 时间格式转换 yyyy-mm-dd
function formatTime2(date) {var year = date.getFullYear()var month = date.getMonth() + 1var day = date.getDate() var hour = date.getHours()var minute = date.getMinutes()var second = date.getSeconds()  return [year, month, day].map(formatNumber).join('-')
}// 时间格式转换 yyyy/mm/dd
function formatTime(date) {var year = date.getFullYear()var month = date.getMonth() + 1var day = date.getDate() var hour = date.getHours()var minute = date.getMinutes()var second = date.getSeconds()  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}// 两位数自动补零
function formatNumber(n) {n = n.toString()return n[1] ? n : '0' + n
}// 计算变化多少天后的日期
function DateAddDay(d, days) {var d = new Date(d); return new Date(d.setDate(d.getDate() + days));
}// 获得本周周日的日期
function FirstDayInThisWeek(d) { var d = new Date(d);  return DateAddDay(d, 0 - d.getDay());
}module.exports = {formatTime,formatTime2,DateAddDay,addZero: formatNumber,FirstDayInThisWeek
}

至此,canlendar 组件的实现已经完成,这个时候就可以进行使用了。

3、canlendar 组件的使用

在pages 文件夹下新建 如下图所示的文件:

然后在calendarday.json 文件中添加如下代码:

{"usingComponents": {"calendarweek":"../../component/calendarweek/calendarweek"}
}

其中 "../../component/calendarweek/calendarweek" 就是我们自定义组件的路径;

"calendarweek" 是我们给组定义组件取得别名,当然你可以可以替换为其它名字,但在使用得时候,你这个地方定义的是什么名字,使用的时候就要用什么名字。

具体在 calendarday.wxml 文件的实现中使用到了我们自定义的组件。

下面看下calendarday 其它文件的具体实现代码。

3.1、calendarday.js 的实现

// pages/calendarday/calendarday.js
Page({/*** 页面的初始数据*/data: {
// 页面总高度将会放在这里
windowHeight: 0,
calendarWeekHeight: 0,
// scroll-view的高度
scrollViewHeight: 0,
title:'',hour_titles: Array.from({ length: 24 }).map(function (value, index) {var hour = (index + 1) % 24;return ((hour < 10) ? "0" : "") + hour + ":00";}),day_hour_items: Array.from({length:24}).map((value,index)=>index+1),todo_item_sizes: Array.from({ length: 24 }).map(function(){return {width:1,height :1}}),bar_item_sizes: Array.from({ length: 24 }).map(function () {return {width: 1,height: 1}}),calendarList:[],curDate:'',testData:[{"key":"测试1","top":1,"height":1},{"key":"测试sssss","top":1,"height":1},{"key":"测试sssss","top":1,"height":1},{"key":"测试sssss","top":1,"height":1},{"key":"测试3","top":2,"height":2},{"key":"测试3","top":2,"height":3},{"key":"测试5","top":10,"height":4},{"key":"测试6","top":1,"height":4},{"key":"测试7","top":30,"height":5},{"key":"测试8","top":5,"height":10},{"key":"测试8","top":60,"height":10}],
},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {},//获取选择的日历数据onMyEvent: function(e){console.log('选择的日期:',e.detail);},//获取组件高度getHeader: function(e){console.log('获取日历组件的高度:',e.detail);let calendarWeekHeight = e.detail;wx.getSystemInfo({success:  res => {this.data.windowHeight = res.windowHeight;}});let scrollViewHeight = this.data.windowHeight - calendarWeekHeight;console.log("scrollViewHeight = ",scrollViewHeight);// 算出来之后存到data对象里面this.setData({scrollViewHeight: scrollViewHeight});},
})

3.1、calendarday.wxml 的实现

<!--pages/calendarday/calendarday.wxml-->
<view class="page"><calendarweek id="calendarweekmenu" bindmyevent="onMyEvent" bindgetHeader="getHeader"></calendarweek><scroll-view scroll-y="true" style="height: {{scrollViewHeight}}px" ><view class='day-content'><view class='day-hour-bar'><view class='day-hour-bar-item' wx:for="{{hour_titles}}" wx:key="{{index}}"><view id="hour-bar-{{index}}" class='item' bindtap='handleTap' style='height:calc(50rpx + {{bar_item_sizes[index].height}} * 50rpx);line-height:calc(50rpx + {{bar_item_sizes[index].height}} * 50rpx)'><block  wx:if="{{item === '00:00'}}"><text>  </text></block><block wx:else><text>{{item}}</text></block></view><view  wx:if="{{index != 0}}" class="day-hour-context-item-div"></view></view></view><view class="day-content-item"  ><view class="day-content-item-sub" wx:for="{{testData}}"><view class="day-content-show" style="margin-top:calc({{item.top}}*10rpx); height:calc({{item.height == 0 ? 1 : item.height}} * 60rpx)" ><text class="day-content-show-tex">{{item.key}}</text></view></view></view></view>
</scroll-view>
</view>

3.3、calendarday.wxss 的实现

/* pages/calendarday/calendarday.wxss */
.page {overflow: scroll;width: 100vw;height: 100vh;
}.day-hour-bar {position: absolute;z-index: 2;width: 100%;
}.day-content {position: relative;z-index: 1;width: 100%;
}.day-hour-bar-item {height: 60rpx;display: flex;flex-direction: row;background-color: #F6F8FA;/* background-color: #B8F1F1;border: 3rpx solid #FCBDAD; *//* line-height: 100rpx; */text-align: center;
}.item {display: inline-block;width: 70rpx;margin-left: 30rpx;margin-top: 10rpx;font-size: 20rpx;font-family: PingFang SC;color: #999999;
}.day-hour-context-item-div{background-color: #DBDCDC;width: 100%;margin-left: 30rpx;height: 2rpx;margin-right: 20rpx;
}.day-content-item{position: relative;z-index: 3;display: flex;margin-left: 110rpx;width: 100%;
}.day-content-item-sub{width: fit-content;
}.day-content-show{border: 2rpx solid #DBDCDC;border-left: 10rpx solid #00B853;border-radius: 5px;background-color: #ffffff;margin-left: 10rpx;overflow:hidden;text-overflow:ellipsis;width: auto;
}

至此,我们的日历/日视图的代码实现已经完成。

如果上面的内容对你有所帮助,不要忘记点个赞哟。

4、运行动态效果图

微信小程序开发--日历/日视图相关推荐

  1. 微信小程序开发导航:精品教程+网友观点+demo源码(5月9日更新)

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

  2. 微信小程序开发系列二:微信小程序的视图设计

    大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...

  3. 微信小程序开发学习4(视图与逻辑)

    微信小程序开发学习4(视图与逻辑) 1.学习目标 能够知道如何实现页面之间的导航跳转 能够知道如何实现下拉刷新效果 能够知道如何实现上拉加载更多效果 能够知道小程序中常用的生命周期函数 2.页面导航 ...

  4. 微信小程序开发学习--7.27日

    微信小程序开发------7.27日学习内容 pages字段 用于描述当前小程序所有页面路径,这是为了让为您客户端知道你当前的小程序页面定义在哪个目录. 小程序在启动时首先加载app.json文件,微 ...

  5. 微信小程序开发demo

    前言 链接: https://pan.baidu.com/s/16j8WCMv2JrRK2OzwvMwZ1w 提取码: 34mp 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么 ...

  6. 微信小程序开发(三)入门之创建打卡活动

    相关文章 微信小程序开发(一)微信开发者工具以及小程序框架介绍 微信小程序开发(二)开发之日历打卡小程序发现页 微信小程序开发(四)入门之打卡功能开发 前言 上篇介绍了日历打卡小程序发现页视图相关开发 ...

  7. Python+微信小程序开发(二)代码构成和宿主环境

    一.小程序代码构成 ​在上一篇文章中,我们通过开发者工具载入模板快速创建了一个QuickStart项目.这个项目里边生成了不同类型的文件: .json 后缀的 JSON 配置文件 .wxml 后缀的  ...

  8. 微信小程序开发教程:项目二微信小程序开发基础 课后习题

    <微信小程序开发教程>主编/黄寿孟 易芳 陶延涛 湖南大学出版社 目录 一.单选题 二.多选题 三.判断题 四.填空题 五.简答题 1.请简单描述页面样式的单位rpx与px的关系. 2.简 ...

  9. 尚硅谷微信小程序开发 仿网易云音乐App 小程序 后端接口服务器搭建

    目录 小程序学习 视频相关的教程文档与笔记分享 配套服务器 源码地址: 接口使用说明文档 接口列表 启动服务 测试服务启动OK网页 http://localhost:3000/test.html​编辑 ...

最新文章

  1. 现成Android 5.0系统源代码
  2. jvm 架构_不可变的基础架构,热部署和JVM
  3. 第10章 32 位 Intel 微处理器编程架构
  4. fatal error C1010: unexpected end of file while looking for precompiled head
  5. 首个智能风控国际标准发布,蚂蚁风控技术入局全球
  6. usb接口驱动_技术丨USB接口无法识别设备的处理方法
  7. 2018.11.09 bzoj4773: 负环(倍增+floyd)
  8. 揭开阿里P2P面纱:大数据是泡泡
  9. Python(二)JavaPython混合编程
  10. 华为机型深色模式下问题
  11. DC-DC电路中自举电容和自举电阻是什么?
  12. macbook air 安装双系统windows10手册及避坑技巧
  13. SPSS Modeler泰坦尼克号幸存者分析
  14. leetcode 寻找峰值
  15. 女装网 www.nzw.com.cn
  16. Jenkins邮箱配置中,使用SSL连接的问题
  17. 生产服务器变慢了排查思路
  18. php 验证 繁体,验证码上中文字是繁体
  19. ADC0809转换器
  20. crmeb 易联云k4小票打印机相关配置说明

热门文章

  1. zabbix应用进阶
  2. 数据挖掘实战分享:财政收入影响因素分析及预测(四)
  3. 安装Git后,鼠标右键没有Git bush here的解决办法
  4. 世上最长情的事唯有陪伴
  5. 直立两轮平衡车核心代码
  6. 视频教程-从零开始自然语言处理-NLP
  7. 基于MATLAB Simulink的三相电压型开环SPWM整流器仿真模型
  8. 智能座舱“域控”背后的新格局
  9. C#入门经典(第7版).pdf
  10. git 撤销commit