日历签到小程序的成功实现方法与策略

why 381 2024-07-02

日历签到小程序的实现

首先我们来看一下最终的效果图:

image.png

下面我们来介绍实现思路:

首先,我们要获取的无非就是每一个格子里面的数据。

先获取月,然后点击月切换到另一个月,到了边界线的时候到了上/下年即可。

那么,怎么获取月的数据呢,可以看到月第一天都是1开始,然后xx天,比如1月31天,我们把它枚举出来。

但是月份受到年份影响,所以计算是否闰年就完成了。

上代码
获取这个月的7*5列表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

let getMothList = (year, month) => {

    var star = new Date(Date.UTC(year, month - 1, 1)).getDay()

    let mn = getMothNum(year)[month - 1]

    var res = []

    var row = []

    new Array(35)

        .fill('')

        .map((_, i) => i - star + 1)

        .map(e =>

            (e > 0 && e <= mn)

            ? ({

                date: `${year}/${month}/${e}`,

                number: e

            })

            : (null)

        )

        .forEach((item, i) => {

            row.push(jsON.parse(JSON.stringify(item)))

            if((i + 1) % 7 == 0){

                res.push(row)

                row = []

            }

        })

    return res

}

然后获取月

1

2

3

4

5

6

var getMaxY = y =>  Boolean(

    y % 4 ==0 && y % 100 != 0 || y % 400==0

)

var getAugNum = n => getMaxY(n) ? 29 : 28

// --获取年对应的月份

var getMothNum = y => ([ 31, getAugNum(y), 31, 30,  31, 30, 31,31, 30, 31, 30, 31 ])

我上面js就这些了(还差上下月切换的没说哈)

但是少了中文的月份,有需要的这个可以再匹配

1

var mothZh = [&#39;一&#39;,&#39;二&#39;,&#39;三&#39;,&#39;四&#39;,&#39;五&#39;,&#39;六&#39;,&#39;七&#39;,&#39;八&#39;,&#39;九&#39;,&#39;十&#39;,&#39;十一&#39;,&#39;十二&#39;].map(e => e + &#39;月&#39;)

然后就是上下月月份了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

up(e){

  var data = e.currentTarget.dataset

  if(data.data == &#39;上&#39;){

    if(this.data.dateM > 1){

      var dateM = this.data.dateM

      var dateY = this.data.dateY

      this.setDate(dateY, dateM - 1)

    }else{

      var dateY = this.data.dateY

      this.setDate(dateY - 1, 12)

    }

  }

},

down(e){

  var data = e.currentTarget.dataset

  if(data.data == &#39;下&#39;){

    if(this.data.dateM < 12){

      var dateM = this.data.dateM

      var dateY = this.data.dateY

      this.setDate(dateY, dateM + 1)

    }else{

      var dateY = this.data.dateY

      this.setDate(dateY + 1, 1)

    }

  }

},

上下月操作好了就是更新数据了,更新数据的时候,因为小程序不能在view里面写逻辑,所以我们在mpa里面操作(这是我的业务逻辑,你们不用管他,我之所以放出来是方便大家查看)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

setDate(dateY, dateM){

  var date_list = getMothList(dateY, dateM)

  .map(e => !e ? e : e.map(day => {

    var cat_date = this.data.cat_date

    return !day ? day : {

      ...day,

      className: this.data.chckin_list.indexOf(day.date) != -1 ? &#39;checkin&#39; : &#39;&#39;,

      sign: day.date == [cat_date.y, cat_date.m, cat_date.d].join(&#39;/&#39;),

      maxToday: +(Date.UTC(day.date.split(&#39;/&#39;)[0], day.date.split(&#39;/&#39;)[1] - 1, +(day.date.split(&#39;/&#39;)[2])))

        > Date.UTC(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),

    }

  }))

  this.setData(({

    dateY,

    dateM,

    date_list,

  }))

  // 获取月和修改的时候,获取签到列表

  this.setSign(dateY, dateM)

  // console.log(date_list)

},

然后会注意到,这里有一个chckin_list,这个就是要渲染出来的啦。 view

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<view class="week">

            <view class="flex" wx:for="{{date_list}}" wx:key="index" wx:for-item="row">

                <view

                class="day {{day.maxToday ? &#39;maxToday&#39; : &#39;&#39;}}"

                wx:for="{{row}}" wx:for-index="row_idx" wx:for-item="day" wx:key="row_idx"

                bind:tap="tapDay"

                data-day="{{day.date}}"

                >

                    <block wx:if="{{day}}">

                        <text class="block to_day_block  {{day.sign ? &#39;select_date&#39; : &#39;&#39;}}" wx:if="{{toDay == day.date}}">今</text>

                        <text class="block  {{day.sign ? &#39;select_date&#39; : &#39;&#39;}}" wx:else>{{day.number}}</text>

                    </block>

                    <view wx:if="{{day.className}}" class="{{day.className}}">已签</view>

                </view>

            </view>

        </view>

上面是我的业务逻辑,其实只需要if,day就行了,因为除了空的,其他都需要渲染。但是一般业务也有是否签到啊,今天以后的灰色不可点击啊(这里没有不可点击是因为用css禁用点击)

其他

之所以没放css,大家css还是自己写吧,如果真有需要,在下面评论。

哦, 如果要看效果,去小程序里面搜索《初九背单词》,点击日历(一个是首页完成今日任务,一个是我的->背单词天数)

(如果有需要,我可以说下签到后台是怎么做的,nodejs)

--好了--

就这样了,晚安

--- 更新部分---

(楼下有人提醒(毛毛饭),3月最后一个31号的不见了,我检查了下,发现被剪切了,因为5 * 7并不能完整展示出来)

修复后的图

image.png

改动部分就是,动态加载行。

基于上面的代码,添加一个判断

image.png

先在前面的35改成6*7。因为多加了一行。 然后再判断是否有空余位置,去掉即可。

1

row.map(e => e || &#39;&#39;).join(&#39;&#39;) !== &#39;&#39;

--完--


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于小程序框架选择的全面分析与考量
下一篇:小程序分享至朋友圈的可行办法与操作
相关文章

 发表评论

暂时没有评论,来抢沙发吧~