<div datePlugin>------------------->position:fixed z-index:100 top:44px width:100% background:#fff
<div vue-datepicker>----------->position:relative margin:0 padding:0
<input name="myDate">-------------->display:none
<div vue-datepicker-panels>-------->position:absolute z-index:9999 left:0 width:100% background:#fff
<div vue-datepicker-panel>
<div vue-datepicker-month></div>------->position:relative height:53px line-height:53px overflow:hidden text-align:center background:#21adfd color:#fff
<table vue-datepicker-tb></table>------>width:100% text-align:center margin-top:4px border-collapse:collpase
<div date-tbody></div>----------------->height:42px
</div>
</div>
</div>
</div>
<div vue-datepicker-month>
<div vue-datepicker-prev></div>--------->position:absolute left:15px top:0 color:#fff font-size:15px cursor:pointer
<div vue-datepicker-btn></div>---------->width:100%
<div vue-datepicker-next></div>--------->position:absolute right:15px top:0 color:#fff font-size:15px cursor:pointer
</div>
<table vue-datepicker-tb>
<thead>-------------------------------->height:35px line-height:35px background:#fff
<tr>------------------------------->border:none
<th></th>---------------------->th:nth-child(1) color:#ff0000
<th></th>---------------------->width:35px font-size:15px border:none font-weight:normal color:#333
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>---------------------->th:nth-last-child(1) color:#ff0000
</tr>
</thead>
</table>
当前月份-----------当前月份的所有日子swipe-item
当前选中的日期-----点击“前一天” “后一天”操作的时候:
1)在当前月份
在当前swipe-item--------选中对应日期
不在当前swipe-item------切换上一个 下一个swipe-item--------选中对应日期
2)不在当前月份
当前月份,当前日期重新赋值,新的swipe-items,选中swipe-item,选中对应日期
构造一个二维数组,-------------->存放当前月份的日期数据:
dayNum = xxx 当前月份天数?
dayArr=[['','',''...],[],[]]--->构造一个6行 * 7列的个元素的二维数组
firstDay=判断当前月份第一天是星期几?
row=0
col=firstDay
for(let d=1; d<=dayNum; d++){
dayArr[row][col] = d---------->col 0~6 ---->row++换行
if(col<6){
col++
}else{
col=0
row++
}
let lastWeekDayNum = 0
for (let i = 0; i < 6; i++) {
if (dayArr[5][i] !== '') {---->日期30 31可能在第6行出现
lastWeekDayNum++------------->统计第6行出现的天数
}
}
if (lastWeekDayNum === 0) {------>第6行没有出现的天数
dayArr.splice(5, 6)-------->dayArr删除第6行全部为空的元素
}
// 获取一个月的日期并按每行7天排列的数组
this.monthDayArr = dayArr
return dayArr
<div class="date-tbody">
<mt-swipe :auto="0" :showIndicators="false" :defaultIndex="defaultIndexVal" :continuous="true" ref="swipeWrapper">
<mt-swipe-item v-for="(m, mIndex) in monthDays" :key="mIndex">---------------------->按照行遍历monthDays
<div v-for="(d, dIndex) in m" v-on:click="choiceDay(d, $event)" :class="classDay(d)" :key="dIndex">------------>按照列遍历每一行里面的元素
<span>{{ d }}</span>
</div>
</mt-swipe-item>
</mt-swipe>
</div>
currWeek (currDay) {
var self = this
for (let n = 0; n < self.monthDayArr.length; n++) {
for (let m = 0; m < self.monthDayArr[n].length; m++) {
if (self.monthDayArr[n][m] === currDay) {--------------->当前选中的日期currDay在二维数组的第几行第几列,切换到该swipe-item
this.$refs.swipeWrapper.defaultIndex = n
this.$refs.swipeWrapper.reInitPages()
self.defaultIndexVal = n
}
}
}
}
classDay (d) {
let that = this
let {month, year, curr} = that
return {
'z-on': curr.day === d && curr.month === month && curr.year === year,-->当前选中的日期
'date-tbody-day z-existed': d !== '',---------------------------------->非空元素
'date-tbody-day': d === '',-------------------------------------------->‘’空元素
'z-invalid': !that.dateIsValid({year, month, day: d})------------------>有效日期(日期没有超出当前时间点)
}
},
choiceDay (d) {---------------------------------------------->通过点击行中的某个列元素,设置为当前选中的日期
let {year, month, format} = this
if (d && this.dateIsValid({year, month, day: d})) {
this.day = d
this.$emit('input', dateFormat(year, month, d, format))----------> 向外层组件v-model="currSelectDate"传出当前选中的日期 v-model相当于 v-on:input="currSelectDate"
if (dateCompare(this.today, {year, month, day: d}) > 0) {-------->当前选中的日期与当前时间点做比较,按钮“后一天”是否可以点击生效
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
}
},
/**
*比较两个日期大小,返回 -1 0 1
* @param date1
* @param date2
* @returns {number}
*/
function dateCompare (date1, date2) {
if (date1.year === date2.year) {
if (date1.day && date2.day) {
if (date1.month === date2.month) {
return date1.day > date2.day ? 1 : (date1.day === date2.day ? 0 : -1)
} else {
return date1.month > date2.month ? 1 : -1
}
} else {
return date1.month > date2.month ? 1 : (date1.month === date2.month ? 0 : -1)
}
} else {
return date1.year > date2.year ? 1 : -1
}
}
/**
* 判断日期是否合法 dateObj格式{year,month,day}
*/
dateIsValid (dateObj) {
let {today, forward, backward, noToday} = this
if (forward && dateCompare(today, dateObj) > 0) {
return false
}
if (backward && dateCompare(today, dateObj) < 0) {
return false
}
if (noToday && dateObj.day && dateCompare(today, dateObj) === 0) {
return false
}
return true
},
prevDay () {
let {year, month, day} = this
if (this.dateIsValid({year, month, day})) {
let monthDayNum
/**
* 判断一个月有几天
*/
if (this.month === 2) {
if (this.year % 4 === 0 && !(this.year % 100 === 0 && this.year % 400 !== 0)) {
monthDayNum = 29
} else {
monthDayNum = 28
}
} else {
if ([1, 3, 5, 7, 8, 10, 0].includes(this.month)) {
monthDayNum = 31
} else {
monthDayNum = 30
}
}
if (this.day > 1) {------------>this.day >= 2
this.day-- ----------->“前一天” this.day--
} else {----------------------->this.day = 1
if (this.month > 0) {-------->this.month>=1 对应>=2月份
this.month-- -------> “前一天” ----->上一个月的最后一天
this.day = monthDayNum
} else {--------------------->this.month=0 一年的第一天
this.year-- -------> “前一天” ----->上一年的最后一天
this.month = 11
this.day = monthDayNum
}
}
let {year, month, format} = this
this.$emit('input', dateFormat(year, month, this.day, format))----------> 向外层组件 v-model="currSelectDate" 传出当前选中的日期 v-model相当于 v-on:input="currSelectDate"
// 点击前一天判断当前日期是否为今日日期,判断是否显示’后一天‘
if (dateCompare(this.today, {year, month, day: this.day}) > 0) {
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
let firstDay = new Date(year, month, 1).getDay() // 每月第一天的位置
let dayArr = new Array(6).fill(0).map(function () {
return new Array(7).fill('')
})
let row = 0
let col = firstDay
for (let d = 1; d <= monthDayNum; d++) {
dayArr[row][col] = d
if (col < 6) {
col++
} else {
col = 0
row++
}
}
let lastWeekDayNum = 0
for (let i = 0; i < 6; i++) {
if (dayArr[5][i] !== '') {
lastWeekDayNum++
}
}
if (lastWeekDayNum === 0) {
dayArr.splice(5, 6)
}
// 获取一个月的日期并按每行7天排列的数组
this.monthDayArr = dayArr
this.currWeek(this.day)---------------->当前选中的日期所在的week,切换到对应swipe-item
}
},
nextDay () {
let {year, month, day} = this
if (this.dateIsValid({year, month, day})) {
let monthDayNum
/**
* 判断一个月有几天
*/
var m = this.month + 1
if (m === 2) {
if (this.year % 4 === 0 && !(this.year % 100 === 0 && this.year % 400 !== 0)) {
monthDayNum = 29
} else {
monthDayNum = 28
}
} else {
if ([1, 3, 5, 7, 8, 10, 12].includes(m)) {
monthDayNum = 31
} else {
monthDayNum = 30
}
}
if (this.day < monthDayNum) {
this.day++
} else {
if (this.month < 11) {
this.month++
this.day = 1
} else {
this.year++
this.month = 0
this.day = 1
}
}
let {year, month, format} = this
this.$emit('input', dateFormat(year, month, this.day, format))
/**
* 点击后一天判断当前日期是否为今日日期,判断是否显示’后一天‘
*/
if (dateCompare(this.today, {year, month, day: this.day}) > 0) {
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
this.currWeek(this.day)
}
},
<div vue-datepicker>----------->position:relative margin:0 padding:0
<input name="myDate">-------------->display:none
<div vue-datepicker-panels>-------->position:absolute z-index:9999 left:0 width:100% background:#fff
<div vue-datepicker-panel>
<div vue-datepicker-month></div>------->position:relative height:53px line-height:53px overflow:hidden text-align:center background:#21adfd color:#fff
<table vue-datepicker-tb></table>------>width:100% text-align:center margin-top:4px border-collapse:collpase
<div date-tbody></div>----------------->height:42px
</div>
</div>
</div>
</div>
<div vue-datepicker-month>
<div vue-datepicker-prev></div>--------->position:absolute left:15px top:0 color:#fff font-size:15px cursor:pointer
<div vue-datepicker-btn></div>---------->width:100%
<div vue-datepicker-next></div>--------->position:absolute right:15px top:0 color:#fff font-size:15px cursor:pointer
</div>
<table vue-datepicker-tb>
<thead>-------------------------------->height:35px line-height:35px background:#fff
<tr>------------------------------->border:none
<th></th>---------------------->th:nth-child(1) color:#ff0000
<th></th>---------------------->width:35px font-size:15px border:none font-weight:normal color:#333
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>---------------------->th:nth-last-child(1) color:#ff0000
</tr>
</thead>
</table>
当前月份-----------当前月份的所有日子swipe-item
当前选中的日期-----点击“前一天” “后一天”操作的时候:
1)在当前月份
在当前swipe-item--------选中对应日期
不在当前swipe-item------切换上一个 下一个swipe-item--------选中对应日期
2)不在当前月份
当前月份,当前日期重新赋值,新的swipe-items,选中swipe-item,选中对应日期
构造一个二维数组,-------------->存放当前月份的日期数据:
dayNum = xxx 当前月份天数?
dayArr=[['','',''...],[],[]]--->构造一个6行 * 7列的个元素的二维数组
firstDay=判断当前月份第一天是星期几?
row=0
col=firstDay
for(let d=1; d<=dayNum; d++){
dayArr[row][col] = d---------->col 0~6 ---->row++换行
if(col<6){
col++
}else{
col=0
row++
}
let lastWeekDayNum = 0
for (let i = 0; i < 6; i++) {
if (dayArr[5][i] !== '') {---->日期30 31可能在第6行出现
lastWeekDayNum++------------->统计第6行出现的天数
}
}
if (lastWeekDayNum === 0) {------>第6行没有出现的天数
dayArr.splice(5, 6)-------->dayArr删除第6行全部为空的元素
}
// 获取一个月的日期并按每行7天排列的数组
this.monthDayArr = dayArr
return dayArr
<div class="date-tbody">
<mt-swipe :auto="0" :showIndicators="false" :defaultIndex="defaultIndexVal" :continuous="true" ref="swipeWrapper">
<mt-swipe-item v-for="(m, mIndex) in monthDays" :key="mIndex">---------------------->按照行遍历monthDays
<div v-for="(d, dIndex) in m" v-on:click="choiceDay(d, $event)" :class="classDay(d)" :key="dIndex">------------>按照列遍历每一行里面的元素
<span>{{ d }}</span>
</div>
</mt-swipe-item>
</mt-swipe>
</div>
currWeek (currDay) {
var self = this
for (let n = 0; n < self.monthDayArr.length; n++) {
for (let m = 0; m < self.monthDayArr[n].length; m++) {
if (self.monthDayArr[n][m] === currDay) {--------------->当前选中的日期currDay在二维数组的第几行第几列,切换到该swipe-item
this.$refs.swipeWrapper.defaultIndex = n
this.$refs.swipeWrapper.reInitPages()
self.defaultIndexVal = n
}
}
}
}
classDay (d) {
let that = this
let {month, year, curr} = that
return {
'z-on': curr.day === d && curr.month === month && curr.year === year,-->当前选中的日期
'date-tbody-day z-existed': d !== '',---------------------------------->非空元素
'date-tbody-day': d === '',-------------------------------------------->‘’空元素
'z-invalid': !that.dateIsValid({year, month, day: d})------------------>有效日期(日期没有超出当前时间点)
}
},
choiceDay (d) {---------------------------------------------->通过点击行中的某个列元素,设置为当前选中的日期
let {year, month, format} = this
if (d && this.dateIsValid({year, month, day: d})) {
this.day = d
this.$emit('input', dateFormat(year, month, d, format))----------> 向外层组件v-model="currSelectDate"传出当前选中的日期 v-model相当于 v-on:input="currSelectDate"
if (dateCompare(this.today, {year, month, day: d}) > 0) {-------->当前选中的日期与当前时间点做比较,按钮“后一天”是否可以点击生效
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
}
},
/**
*比较两个日期大小,返回 -1 0 1
* @param date1
* @param date2
* @returns {number}
*/
function dateCompare (date1, date2) {
if (date1.year === date2.year) {
if (date1.day && date2.day) {
if (date1.month === date2.month) {
return date1.day > date2.day ? 1 : (date1.day === date2.day ? 0 : -1)
} else {
return date1.month > date2.month ? 1 : -1
}
} else {
return date1.month > date2.month ? 1 : (date1.month === date2.month ? 0 : -1)
}
} else {
return date1.year > date2.year ? 1 : -1
}
}
/**
* 判断日期是否合法 dateObj格式{year,month,day}
*/
dateIsValid (dateObj) {
let {today, forward, backward, noToday} = this
if (forward && dateCompare(today, dateObj) > 0) {
return false
}
if (backward && dateCompare(today, dateObj) < 0) {
return false
}
if (noToday && dateObj.day && dateCompare(today, dateObj) === 0) {
return false
}
return true
},
prevDay () {
let {year, month, day} = this
if (this.dateIsValid({year, month, day})) {
let monthDayNum
/**
* 判断一个月有几天
*/
if (this.month === 2) {
if (this.year % 4 === 0 && !(this.year % 100 === 0 && this.year % 400 !== 0)) {
monthDayNum = 29
} else {
monthDayNum = 28
}
} else {
if ([1, 3, 5, 7, 8, 10, 0].includes(this.month)) {
monthDayNum = 31
} else {
monthDayNum = 30
}
}
if (this.day > 1) {------------>this.day >= 2
this.day-- ----------->“前一天” this.day--
} else {----------------------->this.day = 1
if (this.month > 0) {-------->this.month>=1 对应>=2月份
this.month-- -------> “前一天” ----->上一个月的最后一天
this.day = monthDayNum
} else {--------------------->this.month=0 一年的第一天
this.year-- -------> “前一天” ----->上一年的最后一天
this.month = 11
this.day = monthDayNum
}
}
let {year, month, format} = this
this.$emit('input', dateFormat(year, month, this.day, format))----------> 向外层组件 v-model="currSelectDate" 传出当前选中的日期 v-model相当于 v-on:input="currSelectDate"
// 点击前一天判断当前日期是否为今日日期,判断是否显示’后一天‘
if (dateCompare(this.today, {year, month, day: this.day}) > 0) {
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
let firstDay = new Date(year, month, 1).getDay() // 每月第一天的位置
let dayArr = new Array(6).fill(0).map(function () {
return new Array(7).fill('')
})
let row = 0
let col = firstDay
for (let d = 1; d <= monthDayNum; d++) {
dayArr[row][col] = d
if (col < 6) {
col++
} else {
col = 0
row++
}
}
let lastWeekDayNum = 0
for (let i = 0; i < 6; i++) {
if (dayArr[5][i] !== '') {
lastWeekDayNum++
}
}
if (lastWeekDayNum === 0) {
dayArr.splice(5, 6)
}
// 获取一个月的日期并按每行7天排列的数组
this.monthDayArr = dayArr
this.currWeek(this.day)---------------->当前选中的日期所在的week,切换到对应swipe-item
}
},
nextDay () {
let {year, month, day} = this
if (this.dateIsValid({year, month, day})) {
let monthDayNum
/**
* 判断一个月有几天
*/
var m = this.month + 1
if (m === 2) {
if (this.year % 4 === 0 && !(this.year % 100 === 0 && this.year % 400 !== 0)) {
monthDayNum = 29
} else {
monthDayNum = 28
}
} else {
if ([1, 3, 5, 7, 8, 10, 12].includes(m)) {
monthDayNum = 31
} else {
monthDayNum = 30
}
}
if (this.day < monthDayNum) {
this.day++
} else {
if (this.month < 11) {
this.month++
this.day = 1
} else {
this.year++
this.month = 0
this.day = 1
}
}
let {year, month, format} = this
this.$emit('input', dateFormat(year, month, this.day, format))
/**
* 点击后一天判断当前日期是否为今日日期,判断是否显示’后一天‘
*/
if (dateCompare(this.today, {year, month, day: this.day}) > 0) {
this.nextDayBtnToggle = true
} else {
this.nextDayBtnToggle = false
}
// 如果当前选中日期为1号时隐藏前一天按钮
/* if (this.day === 1) {
this.prevDayBtnToggle = false
} else {
this.prevDayBtnToggle = true
} */
this.currWeek(this.day)
}
},