【uniapp3】分享一个自己写的h5日历组件

简言

分享一下自己基于uniapp写的日历组件。如果不太满足你的需求,可以自己改造。
在这里插入图片描述

日历

实现分析:

  • 页面显示 - 分为顶部显示和日历显示,我这里做了多行和单行显示两种情况,主要是当时看着手机的日历做的,手机上的日历单行和多行显示切换特别丝滑,但是我没实现出来。(我觉得限制原因是当时水平不够,再加上滚动用的uniapp的swipper组件,不能定制化实现)。
  • 分屏滚动 - 使用 uniapp的swipper组件,我这里,单行使用这个月周+上个月最后一周+下个月最后一周数据,多行使用这个月+上个月+下个月数据;这样处理的原因是在进行月份切换的时候可以先显示数据然后进行数据更新,实现无感无限切换滚动。
  • 各种事件 - 点击日期发送选中日期的数据。
  • 数据逻辑 - 主要是先确定你想要的数据结构,然后以这个为单位组装成行(周)数组或多行(月)数组。

没有自己实现滚动,也算是取了巧。感觉难点就是日期的数据处理 和 滚动,已经单多行切换了。

代码: uniapp写的 vue2和vue3应该都能用,样式注意使用了sass。

<template>
  <view class="calendar">
    <view class="wrapper">
      <slot
        name="top"
        :nowMonthText="nowMonthText"
        :pickerMonth="pickerMonth"
        :prevMonth="prevMonth"
        :nextMonth="nextMonth"
      >
        <view class="top">
          <view class="month-box">
            <view class="month-text">
              <view class="uni-input" @tap="pickerMonth">{
  
  {
                nowMonthText
              }}</view>
            </view>
            <view class="back-today" @tap="goToday">回到今天</view>
          </view>
          <view class="top-left">
            <view class="icon-arrow arrow-left" @tap="previousFn"></view>
            <view class="icon-arrow arrow-right" @tap="nextFn"></view>
          </view>
        </view>
      </slot>
      <view class="calender-box">
        <view class="head-title">
          <view
            class="head-title-item"
            v-for="v in calenderTitleList"
            :key="v"
            >{
  
  { v }}</view
          >
        </view>
        <!-- 一行显示 -->

        <swiper
          v-if="showType === 1"
          class="row-swiper"
          circular
          :disable-programmatic-animation="true"
          :duration="duration"
          :current="swiperCurrent"
          @change="swipereChangFn"
        >
          <swiper-item
            v-for="(v, index) in calenderRowDaysList"
            :key="index"
            :item-id="v.label"
          >
            <view class="row-days-list">
              <view
                class="days-list-item"
                v-for="(item, i) in v.value"
                :key="`${index}-${i}`"
                :class="{
                  used: item.used,
                }"
              >
                <view
                  class="label"
                  v-if="(isNowMonth && item.isNowMonth) || !isNowMonth"
                  :class="{
                    disabled: item.disabled,
                  }"
                  @tap="clickDay(item)"
                >
                  <view
                    class="text"
                    :class="{
                      'active-item':
                        nowSelectDay && nowSelectDay['time'] === item.time,
                      'active-item--disabled':
                        nowSelectDay &&
                        nowSelectDay['time'] === item.time &&
                        item.disabled,
                      'today-text':
                        item.label === '' &&
                        nowSelectDay &&
                        nowSelectDay['time'] !== item.time &&
                        !item.disabled,
                    }"
                  >
                    {
  
  { item.label }}
                  </view>
                  <view
                    v-show="!item.disabled && item.state"
                    class="state-item text-state-item"
                  >
                  </view>
                  <view
                    class="item-adjust"
                    v-if="!item.disabled && item.adjust && item.adjust.value"
                    :class="{ 'text-state-leave': item.adjust.value == '1' }"
                  >
                    {
  
  { item.adjust.value == "1" ? "休" : "课" }}
                  </view>
                </view>
              </view>
            </view>
          </swiper-item>
        </swiper>
        <!-- 全行显示 -->
        <swiper
          v-else
          class="all-swiper"
          circular
          :disable-programmatic-animation="true"
          :duration="duration"
          @change="swipereChangFn"
          :current="swiperCurrent"
          :class="{
            'six-height':
              swiperDaysList[0] && swiperDaysList[0].value.length / 7 === 6,
          }"
        >
          <swiper-item
            v-for="(v, index) in swiperDaysList"
            :key="index"
            :item-id="v.label"
          >
            <view class="days-list">
              <view
                class="days-list-item"
                v-for="(item, i) in v.value"
                :key="`${index}-${i}`"
                :class="{
                  used: item.used,
                }"
              >
                <view
                  class="label"
                  v-if="(isNowMonth && item.isNowMonth) || !isNowMonth"
                  :class="{
                    disabled: item.disabled,
                  }"
                  @tap="clickDay(item)"
                >
                  <view
                    class="text"
                    :class="{
                      'active-item':
                        nowSelectDay && nowSelectDay['time'] === item.time,
                      'active-item--disabled':
                        nowSelectDay &&
                        nowSelectDay['time'] === item.time &&
                        item.disabled,
                      'today-text':
                        item.label === '' &&
                        nowSelectDay &&
                        nowSelectDay['time'] !== item.time &&
                        !item.disabled,
                    }"
                  >
                    {
  
  { item.label }}
                  </view>
                  <view
                    v-show="!item.disabled && item.state"
                    class="state-item"
                  ></view>
                  <view
                    class="item-adjust"
                    v-if="!item.disabled && item.adjust && item.adjust.value"
                    :class="{ 'text-state-leave': item.adjust.value == '1' }"
                  >
                    {
  
  { item.adjust.value == "1" ? "休" : "课" }}
                  </view>
                </view>
              </view>
            </view>
          </swiper-item>
        </swiper>
        <view v-if="!hideArrow" class="arrow-wrapper" @click="showTypeChange">
          <view
            class="arrow-left"
            :class="{ 'arrow-left--up': showType === 0 }"
          ></view>
          <view
            class="arrow-right
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZSK6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值