一个很很很简单的移动端日历

不知道得多久没有写过文章了,从今年开始心情就一直很浮躁,静不下来…

这次写这个东西其实也很简单,主要是帮其他项目的同事写的,有些东西其实还可以继续封装的,但是我太懒了,就交给jym了。

先上图看看效果吧

主要依赖

  • amfe-flexible postcss-pxtorem
  • dayjs
  • vant

这里主要说一下 amfe-flexiblepostcss-pxtorem ,这个就是用来做移动端的适配,就像一般UI给的设计稿都是750px的,但是我们在实际开发的时候可能是不同的,所以用这个来做适配,下面是配置文件

postcss.config.js

const autoprefixer = require('autoprefixer');
const px2rem = require('postcss-pxtorem');

module.exports = {plugins: [autoprefixer(), px2rem({rootValue: 75, unitPrecision: 5, propList: ['*'], selectorBlackList: [//这里样式需要排除vant组件的,因为vant本身就是移动端的样式了'van-']})],
}; 

主要逻辑

工具类

这些工具类就是普通的获取月数什么的,没有什么好讲的

calendar.js

// 判断是否周末
export const isWeekend = (date) => {return [0, 6].includes(new Date(date).getDay())
}

// 获取年份
export const getDateYear = (date) => {return new Date(date).getFullYear()
}

// 获取月份
export const getDateMonth = (date) => {return new Date(date).getMonth() + 1
}

// 获取月份天数
export const getMonthDay = (date) => {let year = new Date(date).getFullYear()let month = new Date(date).getMonth() + 1return new Date(year, month, 0).getDate()
}

// 获取月份第一天是周几
export const getMonthFirstDayOrder = (date) => {let year = new Date(date).getFullYear()let month = new Date(date).getMonth()return new Date(year, month, 1).getDay()
}

// 获取上个月有多少天
export const getPrevMonthDay = (date) => {let year = new Date(date).getFullYear()let month = new Date(date).getMonth()if (month === 0) {year--month = 12}return new Date(year, month, 0).getDate()
} 

月份处理

这里我是采用二维数组的方式来处理每周的数据,而且我们处理月份的时候需要考虑下面几点

  • 普通月份处理(这不是说废话吗),即每个月的第一天是星期几,排在第几位
  • 上个月/下个月处理,上个月是几月份,多少天,是否在同一年(下个月同理)
  • 周末(这里就不考虑节假日什么的了)
  • 要显示多少周,最多可能有6周(1号在周六,因为我这里是以周日为第一位,然后有31天的情况)

下面就是主要的逻辑处理代码了

calendar.vue

 // 初始化日历数据initMonthData(date) {this.dateArr = [[], [], [], [], [], []]// 每个月第一天排在第几位let firstDayOrder = getMonthFirstDayOrder(date)// 选择器选择的年份let selectedYear = getDateYear(date)// 选择器选择的月份let selectedMonth = getDateMonth(date)// 选择器选择的月份天数let selectedMonthDay = getMonthDay(date)// 选择器选择的月份的上个月的总天数let prevMonthDay = getPrevMonthDay(date)// 月份渲染记数let selectedCountDay = 0// 下个月月份渲染记数let nextMonthCountDay = 0// 是否下个月let isNextMonth = falsefor (let weekIndex = 0; weekIndex < 6; weekIndex++) {for (let dayIndex = 0; dayIndex < 7; dayIndex++) {if (weekIndex === 0) {// 第一周需要对某一个月第一天做定位if (firstDayOrder <= dayIndex) {// 当前月selectedCountDay += 1this.$set(this.dateArr[weekIndex], dayIndex, {date: new Date(selectedYear,selectedMonth - 1,selectedCountDay),status: {isCurr: true, // 是否当月isPrev: false, // 是否上个月isNext: false, // 是否下个月// 是否周末isWeekend: isWeekend(new Date(selectedYear, selectedMonth - 1, selectedCountDay))}})} else {// 上个月 因为选择月份是当前月 上个月需要减去1 然后new Date()还需要再减去1let prevMonth = selectedMonth === 1 ? 11 : selectedMonth - 2let prevMonthYear =selectedMonth - 1 === 0 ? selectedYear - 1 : selectedYearthis.$set(this.dateArr[weekIndex], dayIndex, {date: new Date(prevMonthYear,prevMonth,prevMonthDay - firstDayOrder + dayIndex + 1),status: {isCurr: false,isPrev: true,isNext: false,isWeekend: isWeekend(new Date(prevMonthYear,prevMonth,prevMonthDay - firstDayOrder + dayIndex + 1))}})}} else {selectedCountDay += 1isNextMonth = selectedCountDay > selectedMonthDayif (!isNextMonth) {// 当前月this.$set(this.dateArr[weekIndex], dayIndex, {date: new Date(selectedYear,selectedMonth - 1,selectedCountDay),status: {isCurr: true,isPrev: false,isNext: false,isWeekend: isWeekend(new Date(selectedYear, selectedMonth - 1, selectedCountDay))}})} else {// 下个月let nextMonth = selectedMonth === 12 ? 0 : selectedMonthlet nextYear =selectedMonth === 12 ? selectedYear + 1 : selectedYearnextMonthCountDay += 1this.$set(this.dateArr[weekIndex], dayIndex, {date: new Date(nextYear, nextMonth, nextMonthCountDay),status: {isCurr: false,isPrev: false,isNext: true,isWeekend: isWeekend(new Date(nextYear, nextMonth, nextMonthCountDay))}})}}}}while (getDateMonth(this.dateArr[this.dateArr.length - 1][0].date) !==selectedMonth) {// 某些月份不用六个星期 去除不需要的数据this.dateArr.pop()}}, 

部分样式处理

就是根据item里面的状态进行动态class处理

 handleDayClass(item, dayIndex, weekIndex) {let classStr = `${item.status.isWeekend || item.status.isNext || item.status.isPrev? ' day_prev_next_weekend': ''}${dayjs(item.date).isSame(dayjs(this.currDate), 'day') ? ' day_curr' : ''}${dayIndex === this.clickDayIndex && weekIndex === this.clickWeekIndex? ' day_active': ''}`return classStr} 

然后那个弹窗就是用vant组件的van-popover,然后再初始化的时候给每一个item设置一个值与对应组件绑定,记得用$set,不然数据可能是视图不对应。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值