小程序日歷組件

legend.png

主要邏輯:

//目標(biāo)月1號(hào)對(duì)應(yīng)的星期 
let startWeek = new Date(year, month, 1).getDay();
//獲取某年某月的天數(shù)(最后一天即天數(shù)
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//事件類型
}

其他的沒(méi)啥好講的,只是一些事件的顯示,直接上代碼,需要拿走

// components/calendar.js
Component({
  properties: {
    // 是否顯示前后月預(yù)覽日期
    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) {
      //全部時(shí)間的月份都是按0~11基準(zhǔn),顯示月份才+1 
      let dateArr = []; //需要遍歷的日歷數(shù)組數(shù)據(jù) 
      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);
      //目標(biāo)月1號(hào)對(duì)應(yīng)的星期 
      let startWeek = new Date(year, month, 1).getDay();
      //獲取目標(biāo)月有多少天 
      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() {
      //全部時(shí)間的月份都是按0~11基準(zhǔn),顯示月份才+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() {
      //全部時(shí)間的月份都是按0~11基準(zhǔn),顯示月份才+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; 
} 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天我們一起寫一個(gè)微信小程序日歷組件 微信小程序日歷組件https://github.com/749264345/...
    什么都穩(wěn)了閱讀 2,880評(píng)論 1 7
  • # 微信小程序日歷組件開(kāi)發(fā) 微信小程序基礎(chǔ)知識(shí) 微信小程序 框架介紹 組件文檔 上述是開(kāi)發(fā)小程序的基本知識(shí)。 今天...
    zhaovov閱讀 21,242評(píng)論 2 4
  • 作為一個(gè)合格的開(kāi)發(fā)者,不要只滿足于編寫了可以運(yùn)行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個(gè)周閱讀 8,686評(píng)論 1 33
  • (一)如何打造自己的付費(fèi)產(chǎn)品? 從今年的四月份開(kāi)始,知識(shí)付費(fèi)產(chǎn)品的訂閱率和打開(kāi)率都大幅度下滑,大家都說(shuō),已經(jīng)到了知...
    茜喵閱讀 764評(píng)論 7 12
  • 自人類大規(guī)模發(fā)展并使用電力以來(lái),加之互聯(lián)網(wǎng)的興起,手機(jī)的地位也穩(wěn)固了起來(lái),彼時(shí),國(guó)度的原始統(tǒng)治者被手機(jī)所取代,...
    朱斌_ece5閱讀 204評(píng)論 0 0

友情鏈接更多精彩內(nèi)容