小程序日历组件

legend.png

主要逻辑:

//目标月1号对应的星期 
let startWeek = new Date(year, month, 1).getDay();
//获取某年某月的天数(最后一天即天数
const dayNums = new Date(year, month+1, 0).getDate();

组件使用

<calendar events="{{events}}" bindclick="clikCalendar" />
// data
const events = [{
      date: "1564675200000"
    }, {
      date: "2019/7/15",
      type: "olive"
    }, {
      date: 1566316800000,
      type: "olive"
    }]
{
date,//选中日期
type//事件类型
}

其他的没啥好讲的,只是一些事件的显示,直接上代码,需要拿走

// components/calendar.js
Component({
  properties: {
    // 是否显示前后月预览日期
    preview: {
      type: Boolean,
      value: true
    },
    /** 
     * 日期事件 
     * [{date, type}]
     * date
     * type "green" "olive"
    */
    events: {
      type: [Object, Array],
      observer(value, old) {
        let events = []
        if (this.toType(value) === "array") {
          if (value.length == 0) return
          for (let i = 0; i < value.length; i++) {
            const date = (new Date(value[i].date)).getTime() ? new Date(value[i].date) : new Date(parseInt(value[i].date))

            if (!date.getTime()) continue
            const event = {
              date: date.toLocaleDateString(),
              type: value[i].type || "green"
            }
            events.push(event)
          }
        } else {
          const date = (new Date(value.date)).getTime() ? new Date(value.date) : new Date(parseInt(value.date))

          if (!date.getTime()) return
          const event = {
            date: date.toLocaleDateString(),
            type: value.type || "green"
          }
          events.push(event)
        }
        console.log(events)
        this.setData({ _events: events })
        this.dateInit();
      }
    }
  },
  data: {
    year: 0,
    month: 0,
    date: ['日', '一', '二', '三', '四', '五', '六'],
    dateArr: [],
    isTodayWeek: false,
    todayIndex: 0,
    _events: []
  },
  attached() {
    let now = new Date();
    let year = now.getFullYear();
    let month = now.getMonth() + 1;
    this.dateInit();
    this.setData({
      year: year,
      month: month
    })
  },
  methods: {
    dateInit(setYear, setMonth) {
      //全部时间的月份都是按0~11基准,显示月份才+1 
      let dateArr = []; //需要遍历的日历数组数据 
      let now = setYear ? new Date(setYear, setMonth) : new Date();
      let year = now.getFullYear();
      let month = now.getMonth();
      let nextYear = (month + 1) > 11 ? (year + 1) : year;
      let nextMonth = (month + 1) > 11 ? 0 : (month + 1);
      //目标月1号对应的星期 
      let startWeek = new Date(year, month, 1).getDay();
      //获取目标月有多少天 
      let dayNums = new Date(nextYear, nextMonth, 0).getDate();
      let obj = {}
      const nextDays = 6 * 7 - startWeek - dayNums
      const today = new Date().toLocaleDateString()
      for (let i = 0; i < (startWeek + dayNums); i++) {
        const num = i - startWeek + 1;
        const curDay = new Date(year, month, num).toLocaleDateString()
        if (num > 0) {
          obj = {
            curDay,
            dateNum: new Date(curDay).getDate(),
            event: today === curDay && 'blue'
          }
        } else {
          if (this.data.preview) {
            obj = {
              curDay,
              dateNum: new Date(curDay).getDate(),
              event: "preview"
            };
          } else {
            obj = {}
          }
        }
        dateArr[i] = obj;
      }
      if (this.data.preview) {
        for (let i = 0; i < nextDays; i++) {
          const curDay = new Date(year, month + 1, i + 1).toLocaleDateString()
          dateArr[startWeek + dayNums + i] = {
            curDay,
            dateNum: new Date(curDay).getDate(),
            event: "preview"
          };
        }
      }
      // 添加事件
      dateArr.forEach(value => {
        this.data._events.forEach(event => {
          if (event.date === value.curDay) {
            value.event = event.type
          }
        })
      })
      this.setData({
        dateArr: dateArr
      })
      // console.log(dateArr)

      let nowDate = new Date();
      let nowYear = nowDate.getFullYear();
      let nowMonth = nowDate.getMonth();
      let nowWeek = nowDate.getDay();
      let getYear = setYear || nowYear;
      let getMonth = setMonth >= 0 ? setMonth : nowMonth;

      if (nowYear == getYear && nowMonth == getMonth) {
        this.setData({
          isTodayWeek: true,
          todayIndex: nowWeek
        })
      } else {
        this.setData({
          isTodayWeek: false,
          todayIndex: -1
        })
      }
    },
    lastMonth() {
      //全部时间的月份都是按0~11基准,显示月份才+1 
      let year = this.data.month <= 1 ? this.data.year - 1 : this.data.year;
      let month = this.data.month <= 1 ? 12 : this.data.month - 1;
      this.setData({
        year: year,
        month: month
      })
      this.dateInit(year, month - 1);
    },
    nextMonth() {
      //全部时间的月份都是按0~11基准,显示月份才+1 
      let year = this.data.month > 11 ? this.data.year + 1 : this.data.year;
      let month = this.data.month > 11 ? 1 : this.data.month + 1;
      this.setData({
        year: year,
        month: month
      })
      this.dateInit(year, month - 1);
    },
    click(e) {
      const idx = e.currentTarget.dataset.idx
      const item = this.data.dateArr[idx];
      this.triggerEvent("click", item)
    },
    toType(obj) {
      return Object.prototype.toString
        .call(obj)
        .match(/\s([a-zA-Z]+)/)[1]
        .toLowerCase();
    }
  }
})
<view class='wrap'>
  <view class='date_show'>
    <view class='show_arrow' bindtap='lastMonth'>
      <view class='arrow left'></view>
    </view>
    <view class='show_title'>{{year}}年{{month}}月</view>
    <view class='show_arrow' bindtap='nextMonth'>
      <view class='arrow right'></view>
    </view>
  </view>
  <view class='content_box'>
    <view wx:for='{{date}}' wx:key="{{index}}" class='header {{(index == todayIndex) && isTodayWeek ? "weekMark" : ""}}'>{{item}}
    </view>
  </view>
  <view class='content_box'>
    <view wx:for='{{dateArr}}' wx:key="{{index}}" class='content {{item.event}}'  catchtap='click' data-idx='{{index}}'>
      <view class='date-head'>
        <view>{{item.dateNum}}</view>
      </view>
    </view>
  </view>
</view>
.date_show{ 
  position: relative; 
  width: 90vw; 
  display: flex;
  align-items: center;
  font-size: 30rpx; 
  color: #282828; 
  margin: 0 auto; 
}
.show_arrow {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20rpx 0;
}
.show_title {
  flex: 2.5;
  text-align: center;
}
.arrow {
  width: 20rpx;
  height: 20rpx;
  border-top: 2px solid #666;
  border-right: 2px solid #666;
}
.arrow.left {
  transform: rotate(-135deg);
}
.arrow.right {
  transform: rotate(45deg);
}

.content_box{
  display: flex;
  flex-wrap: wrap;
  padding: 0 24rpx; 
  min-width: 600rpx;
  max-width: 840rpx;
}
.content_box .header {
  width: calc(100% / 7); 
  color: #333; 
  font-size: 30rpx; 
  text-align: center; 
  border-bottom: 1px solid #D0D0D0; 
  padding: 30rpx 0; 
}
.weekMark{ 
  position: relative; 
  top: -2px;
  border-bottom: 2px solid #22A7F6 !important; 
} 
.content_box .content{
  position: relative; 
  width: calc(100% / 7); 
  font-size: 26rpx; 
  text-align: center; 
  vertical-align: middle; 
  margin: 15rpx 0; 
}
.date-head{ 
  width: 60rpx; 
  height: 60rpx; 
  line-height: 60rpx; 
  margin: 0 auto; 
  text-align: center; 
  border-radius: 50%; 
} 

.preview .date-head {
  color: #c0c4cc;
}
.blue .date-head{ 
  color: #fff; 
  background-color: #22A7F6; 
} 
.olive .date-head{ 
  color: #fff; 
  background-color: olive; 
} 
.green .date-head{ 
  color: #fff; 
  background-color: green; 
} 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 今天我们一起写一个微信小程序日历组件 微信小程序日历组件https://github.com/749264345/...
    什么都稳了阅读 2,728评论 1 7
  • # 微信小程序日历组件开发 微信小程序基础知识 微信小程序 框架介绍 组件文档 上述是开发小程序的基本知识。 今天...
    zhaovov阅读 20,862评论 2 4
  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,428评论 1 33
  • (一)如何打造自己的付费产品? 从今年的四月份开始,知识付费产品的订阅率和打开率都大幅度下滑,大家都说,已经到了知...
    茜喵阅读 699评论 7 12
  • 自人类大规模发展并使用电力以来,加之互联网的兴起,手机的地位也稳固了起来,彼时,国度的原始统治者被手机所取代,...
    朱斌_ece5阅读 144评论 0 0