项目背景
h5项目,基于vue2和vant
需求
需要有周报形式的,滚轮选取日期组件,效果如上图
解决方案
在vant组件库中datetimepicker组件,有相关样式,但是并没有周的形式,所以要基于datetimepicker去修改组件,解决时使用到了dayjs。上代码
template模板
<template>
<div id="app">
<van-datetime-picker
v-model="currentDate"
type="date"
title="选择年月日"
:min-date="minDate"
:max-date="maxDate"
:filter="filter"
@change="change"
@confirm="confirm"
/>
</div>
</template>
js代码
<script>
import dayjs from 'dayjs'
export default {
name: 'App',
data(){
return {
//选择器的最小时间
minDate: new Date(2020, 0, 1),
//选择器的最大时间
maxDate: new Date(2025, 10, 1),
//双向绑定时间
currentDate: new Date(2021, 0, 17),
//自定义周选项的数组
newOptions:[],
//拿到的真实时间
week:null
}
},
mounted(){
//mounted就得初始化自定义周选项,getNewOptions这个方法传入一个带年和月份的日期对象,返回这个月的对应日期周数组
this.newOptions = this.getNewOptions(this.currentDate)
},
methods:{
//这是vant组件提供的方法来方便我们自定义周选项
filter(type, options) {
if (type === 'day') {
return this.newOptions;
}
return options;
},
//这也是vant提供的方法,当选择器时间改变触发
change(e){
//e是选择器实例,它有一方法getValues来让我们拿到选择的日期周,需要在DOM后拿到最新的
this.$nextTick(()=>{
this.week = e.getValues()
})
//每次改变初始化自定义周数组
this.newOptions = this.getNewOptions(this.currentDate)
},
//点击确定后触发
confirm(){
console.log(this.week)
},
//getNewOptions核心就是这个方法,传入一个年和月,返回这个月对应得日期周数组
getNewOptions(month) {
const daysInMonth = dayjs(month).daysInMonth()
const date = dayjs(month).format('YYYY/MM')
const week = new Date(date + '/01').getDay()
let StringWeeks = null
if (week == 0) {
StringWeeks = dayjs(date).add(1, 'day').format('YYYY/MM/DD')
} else if (week == 1) {
StringWeeks = dayjs(date + '/01').format('YYYY/MM/DD')
} else {
StringWeeks = dayjs(date).add(8 - week, 'day').format('YYYY/MM/DD')
}
try {
const t = dayjs(StringWeeks).format('D')
const times = (daysInMonth - (t - 1)) / 7
const optionsArr = []
let day = dayjs(StringWeeks).format('MM/DD')
optionsArr.push(day)
for (let i = 1; i <= Math.ceil(times); i++) {
StringWeeks = dayjs(StringWeeks).add(6, 'day')
day = dayjs(StringWeeks).format('MM/DD')
optionsArr.push(day)
StringWeeks = dayjs(StringWeeks).add(1, 'day')
day = dayjs(StringWeeks).format('MM/DD')
optionsArr.push(day)
}
console.log(optionsArr, 'optionsArr')
optionsArr.length % 2 == 0 ? '' : optionsArr.pop()
this.arrSplicing(optionsArr)
console.log(optionsArr)
return this.arrSplicing(optionsArr)
} catch (err) {
alert(err, 'er')
}
},
//这个方法辅助getNewOptions
arrSplicing(arr) {
let newArr = []
let flag = 0
for (let i = 1; i <= arr.length / 2; i++) {
newArr.push(`${arr[flag]}-${arr[flag + 1]}`)
flag += 2
}
return newArr
}
},
}
</script>