欢迎点赞!
背景
最近为我开源的小项目:微信小程序扩充自定义组件库(点击去GitHub) 增加了一个新组件 —— 日历组件。
正文
在编撰过程中,因为你们都晓得,日历组件是有固定行数和每一行的固定列数的(即使当前小方块内没有值),所以结合小程序“数据优先”的特征,最合适的布局形式一定是flex了!
说一下大致思路(布局上),笔者将整个组件分为两部份:分别是
头部的当前日期(年月)显示,以及左右两边的切换按键
当前切换月份的日期显示
头部的布局自不多说:一个 display:flex; 加上 align-items:center; 居中简直完美。底部的日期显示我是采用的“将整体分为六行,每一行七列”的布局形式 —— 因为一个月最多31天,每一周最多7天,6X7=42,行数六行足够使用。(而且现今基本上月历都是6行7列的)
这样的话我就给每一行设置相同的class,让其再用flex规范子元素(子组件):
#4:e:2:c:e:3:f:e:d:4:e:9:2:d:3:b:c:f:a:d:5:b:1:7:9:d:b:5:b:f:c:d#
(代码中倒数第七、八行的判定是检验是否是当前日期(now_selectedDate)或选中日期(selectedDate),为其加特殊疗效,对布局不导致影响)
#4:4:8:d:3:1:8:f:7:7:f:3:b:1:0:c:5:b:5:3:8:8:c:4:7:f:f:3:0:4:6:8#
布局方完成,我满心欢喜的按下ctrl+s,发现:
#4:6:b:e:2:d:e:c:0:a:6:b:8:9:4:5:2:9:4:1:8:b:5:f:d:c:b:a:a:d:f:0#
可以看见:控制每一行的类是 “calendar_box”,那么毫无疑问,导致出现如图缘由肯定是这种中有这样一行代码:
#6:e:d:f:d:2:a:6:1:1:e:9:c:9:2:e:4:0:f:5:b:c:e:e:2:b:1:e:c:f:a:0#
果不其然!
在本项目中,我的解决方式很简单:将这一行代码去除,那么由此引起的宽高问题如何解决?这个问题,css给出了解决方案—— calc() !我将“每一行”的高度设为外部view的1/6:height:calc(100% / 6) ,每一行中列的长度设为整行长度的1/7:width:calc(100% / 7)根据CSS文档流的特性,这些元素都会一个接一个的排列,贼好看的那个~(去这儿)
★
有了calc等css3函数的“加盟”,可以预见这些纯‘原生’的解决方法将会越来越多的被使用到各类场景。
”
#0:b:6:c:d:5:2:2:f:3:9:8:6:0:a:9:e:4:e:4:4:8:2:a:8:1:8:f:5:c:a:7#
sucess
刚才说了,这个案例中的行列数是固定的 —— 这并不稀少!那么,除了本文提出的解决方式,还能怎样做?
动态改变最后一个元素的长度
我们都晓得,flex布局中还有一个比较知名的概念就是 flex: 1; (flex: auto;)了,他能动态“填满”剩余空间,那么我们再子元素同级位置再加一个元素,对他设置最小长度为子元素相同长度,并且margin和子元素一致:
#0:d:2:2:8:3:2:f:2:a:3:f:0:5:b:a:5:0:9:6:0:9:b:4:d:9:8:d:f:b:9:4#
#2:4:2:2:b:8:a:a:6:b:f:8:1:3:0:3:4:1:0:4:9:2:e:d:8:e:7:3:4:1:d:2#
这个技巧和下一个问题的第一种方式类似,但要简单好多!
根据个数最后一个元素动态margin
简单来说就是:单独设置最后一行的最后一个元素,控制其margin-right因为每一列的数量都是固定的,因此,我们可以估算出不同个数列表应该多大的margin值能够保证完全左对齐。例如,假设每行4个元素,结果最后一行只有3个元素,则最后一个元素的margin-right大小是“列表长度+间隙大小”的话,那最后3个元素也是可以完美左对齐的。然后,借助树结构伪类数目匹配技术,我们可以晓得最后一行有几个元素。例如:
.list:last-child:nth-child(4n - 1)说明最后一行,要么3个元素,要么7个元素……
.list:last-child:nth-child(4n - 2)说明最后一行,要么2个元素,要么6个元素……
#a:5:1:5:f:9:c:a:c:b:b:1:9:6:c:4:5:7:8:8:4:e:0:c:5:c:b:f:8:a:c:a#
那么,如果每一行的列数是不固定的呢?
这个问题的解法有很多种,其中笔者最“推崇”的是——用空白元素占位!使用足够的空白标签进行填充占位:具体的占位数目是由最多列数的个数决定的,例如这个布局最多7列,那我们可以使用7个空白标签进行填充占位,最多10列,那我们须要使用10个空白标签。
#8:b:0:8:a:1:9:2:3:4:e:5:c:4:d:f:b:f:1:7:7:d:c:6:0:4:d:a:d:0:9:9#
这种方式的缺点(同时也是优点)就是:占位的 元素间距和margin设置必须和列表父元素一样即可!
#6:8:3:c:6:f:a:c:4:0:0:6:9:4:7:b:7:9:0:e:3:4:5:2:d:f:2:2:5:a:9:c#
这里要左对齐,则设置i的margin-right;同样的假如右对齐,则需设置margin-left。
还有一种目前被很多人接受的方式就是以前轰动的grid布局 —— 它有天然的单侧对其和小方块间隙,对熟悉grid的人来说,本文这个问题几乎不会出现:
#4:c:d:8:6:2:b:e:9:6:9:d:5:1:1:b:1:0:2:8:c:9:7:1:2:1:c:d:0:c:d:9#
最后再介绍一下这个组件:它在调用时接收两个参数——他们是两个event函数,你须要窃听她们,你可以得到:刚显示组件时的当前日期/星期几和你点击选中日期时选中的年月日和星期几
#2:9:7:e:9:2:3:7:0:c:b:a:6:6:e:f:c:2:4:e:9:1:e:b:c:a:3:f:7:4:a:1#
结尾
以后可能为组件降低哪些功能就把布局形式更新了,到时候再回去补。
临近春节中学没啥课,电脑放工作室没带回,室友笔记本有点不会用,就到这吧。祝诸位新春&国庆快乐,嘿嘿!
最后
#0:6:3:3:9:7:0:c:b:0:3:e:0:e:5:d:c:0:e:2:7:2:6:0:a:1:9:4:b:7:f:6#
#1:1:4:f:8:6:f:d:d:d:4:8:5:2:b:b:d:2:8:f:e:1:4:0:9:2:a:e:f:5:c:c#
点个在看支持我吧
#9:6:c:4:c:d:a:e:a:3:9:c:a:7:e:b:0:4:b:6:9:b:7:d:7:6:0:8:7:2:e:7#