日历组件
日历组件需求
- 在日历中,根据不同的值展现其不同的样式。如现有一个学习时长记录的小程序,在每一天结束的时候填写当天的学习时长'studyTime'。
if( studyTime <= 4 ) { 当前日展示红色 }else { 当前日展示绿色 }
日历组件展现形式
日历组件思路
-
组件分为二块实现,表头和表体
-
表头实现思路
- 考量点:可能周日为每周的第一天,或者周一为每周的第一天
- 具体思路:参照表头数据结构,需要关注的是每个对象的key值,key值将会用来与new Date(year,month,1).getDay()进行比对,匹配的值就代表当前月的第一天对应于第几个表头。表头数据结构:
[ { key: '0', label: '日', }, { key: '1', label: '一', }, { key: '2', label: '二', }, { key: '3', label: '三', }, { key: '4', label: '四', }, { key: '5', label: '五', }, { key: '6', label: '六', } ]
- 如果需要对表头顺序进行切换,只需移动对象之间的顺序即可。但需要保证key值的闭环为0-1-2-3-4-5-6-0。至于第一个key到底是什么并不重要。
-
表体实现思路:
-
考量点:
-
状态样式显示:根据样图可以分析出一下几种情况
1)相邻的日期如果与本身不一致,则背景为一个圆。如7号
2)相邻的日期如果状态一致,则是一整块的背景,且最左边与最右边需要展示为半圆的样式。如12~15号
思考1:怎样实现相邻状态一致则是一整块背景,如果不一致,则会有一定的间隔?如7号与8号。 思考2:状态该如何获取?
-
-
解决方案:
-
渲染日历的数组calendarList长度为7 * 6,极端情况会出现月份占了六行的高度,所以使用7 * 6填充数组。也避免日历组件高度不固定。而calendarList内将根据情况自行填充
-
‘思考1’,实现的解决思路是:在每一个日期右侧放置一个填充块。该填充块颜色如何展示将依据相邻间的状态决定。
-
‘思考2’,思路是通过预先定义一个规则dateStatusRule,规则如下:
dateStatusRule: { key: 'time', //key值:从后端传回的数据对象中取出‘key’值应用在此规则上 range: [ //对应的key值>=8,则标记状态VALID、<8则标记状态INVALID { sign: '>=', value: '8', status: 'VALID' }, { sign: '<', value: '8', status: 'INVALID' } ] },
假使模拟数据为:
mockData = [{ "personName": "张三", "date": "2019-11-01", "time": 0 }, { "personName": "张三", "date": "2019-11-02", "time": 8 }, { "personName": "张三", "date": "2019-11-03", "time": 8 }, { "personName": "张三", "date": "2019-11-04", "time": 8 }, { "personName": "张三", "date": "2019-11-05", "time": 8 }, { "personName": "张三", "date": "2019-11-06", "time": 4 }]
-
声明一个长度为42的dateStatus数组用来存放日期状态。 let dateStatus = new Array(42).fill(''); 对mockData进行遍历获取对应date的status,并将status存放至dateStatus对应的位置。
-
calc.axml中在对calendarList进行遍历渲染时,通过索引获取当前日期所对应的status。在对相邻间的status进行比较来确定展现的样式。
实现代码如下
<block a:for="{{calendarList}}" a:for-item="item" a:for-index="index" key="{{index}}"> <view class="calendar-item {{dateStatus[index] == 'VALID' ? 'calendar-green': (dateStatus[index] == 'INVALID' ? 'calendar-red': '')}} {{dateStatus[index] == dateStatus[index+1] ? 'left-half-radius': 'full-radius'}} {{ index > 0 && dateStatus[index - 1] == dateStatus[index] && dateStatus[index] == dateStatus[index+1] ? 'square': ''}} {{ index > 0 && dateStatus[index - 1] == dateStatus[index] && dateStatus[index] !== dateStatus[index+1]? 'right-half-radius': ''}} {{ index > 0 && dateStatus[index - 1] !== dateStatus[index] && dateStatus[index] !== dateStatus[index+1] ? 'full-radius': ''}}" > <text>{{item}}</text> </view> <view class="calendar-placeholder {{dateStatus[index] == 'VALID' && dateStatus[index] == dateStatus[index+1] ? 'calendar-green': dateStatus[index] == 'INVALID' && dateStatus[index] == dateStatus[index+1] ? 'calendar-red': '' }} {{dateStatus[index] == 'VALID' && index > 0 && dateStatus[index - 1] == dateStatus[index] && dateStatus[index] == dateStatus[index+1] ? 'calendar-green': dateStatus[index] == 'INVALID' && index > 0 && dateStatus[index - 1] == dateStatus[index] && dateStatus[index] == dateStatus[index+1] ? 'calendar-red': '' }}"> </view> </block> class解释: 'square'--方块--border-radius: 0; 'left-half-radius'--左半圆--border-radius: 50% 0 0 50%; 'right-half-radius'--右半圆--border-radius: 0 50% 50% 0; 'calendar-green'--绿色背景 'calendar-red'--红色背景
-
-