目录
代码分享
utils文件
uniapp使用插件使用
zdp-date-picker使用说明
本组件用到了uni-ui的uni-popup弹窗组件
废话不多说直接上代码
代码分享
<template> <view class="content-pop"> <uni-popup ref="popup" type="bottom"> <view class="zdp-pop"> <view class="top-cont"> <view class="close-cont" @click="close(1)"> 取消 </view> <!-- 可以自定义显示 --> <slot name="text" :scope="{range,zdpdate}"> <view class="text-info"> 请选择时间 <view> {{selInfo}} </view> </view> </slot> <view class="save-cont" @click="close(2)"> 确认 </view> </view> <view class="tabs-cont"> <view class="tab-list" v-for="item in tabs" :class="item.value==activeIdx?'active':''" @click="handleTabs(item.value)"> {{item.label}} </view> </view> <view class="date-cont"> <picker-view :value="value" @change="handleChange" class="picker-view"> <picker-view-column v-for="obj in SelArr"> <view class="item" v-for="(item,index) in obj.child" :key="index">{{item}}{{obj.value}} </view> </picker-view-column> </picker-view> </view> </view> </uni-popup> </view></template><script> import { whichWeek } from '../../utils/getWeek.js' import { getMonthStartEnd } from '../../utils/getMonth.js' import { getQuarterDates } from '../../utils/getQuarter.js' export default { props: { type: { type: String, default: '日', validator(value, props) { return ['日', '月', '周', '年', '季'].includes(value) } }, time: { type: String, //'2024-1-1' '2024-2' '2024-2' '2024-2' '2024 } }, data() { return { tabs: [{ label: '日', value: '日' }, { label: '周', value: '周', }, { label: '月', value: '月', }, { label: '季', value: '季', }, { label: '年', value: '年', } ], activeIdx: '日', value: [], //选择的值,要设置默认值 dateArr: [], day: 18, week: 1, month: 1, // quarter: 2, years: 24, SelArr: [], range: '', zdpdate: '' } }, computed: { selInfo() { let str = '' let { activeIdx, years, day, month, week, quarter } = this if (activeIdx == '日') { str = `20${years}年 ${month<10?'0'+month:month}月 ${day}日` } else if (activeIdx == '周') { str = `20${years}年 第${week}周` } else if (activeIdx == '月') { str = `20${years}年 ${month<10?'0'+month:month}月` } else if (activeIdx == '季') { str = `20${years}年 ${quarter}季` } else if (activeIdx == '年') { str = `20${years}年` } return str } }, created() { }, methods: { // handleProps() { let arr = [] arr = this.time.split('-') if (this.type == '日') { this.month = arr[1] - 0 this.day = arr[2] - 0 } else if (this.type == '周') { this.week = arr[1] - 0 } else if (this.type == '季') { this.quarter = arr[1] - 0 } else if (this.type == '月') { this.month = arr[1] - 0 this.quarter = this.handleQuarter(this.month) } for (let i = 0; i < arr.length; i++) { if (i == 0) { arr[0] = arr[0].slice(2) arr[0] -= 0 this.years = arr[0] } else { arr[i]-- } } this.value = arr }, // 初始化 newDate() { // this.activeIdx=this.type const date = new Date() this.day = date.getDate() this.years = date.getFullYear() this.week = this.getYearWeek(date) this.quarter = this.handleQuarter(this.month) this.month = date.getMonth() + 1 this.handleTabs(this.type) if (this.time) { this.handleProps() } this.initArr() }, initArr() { const date = new Date() let arr = [] let { activeIdx, } = this let day = [] let week = [] let month = [] let quarter = [] let years = [] for (let i = 2000; i <= date.getFullYear(); i++) { years.push(i) } for (let i = 1; i <= 12; i++) { month.push(i) } let weekArr = whichWeek(`20${this.years}`) for (let i = 1; i <= weekArr.length; i++) { week.push(i) } for (let i = 1; i <= 4; i++) { quarter.push(i) } if (activeIdx == '日') { let num = this.getMonthDays(this.years, this.month) for (let i = 1; i <= num; i++) { day.push(i) } arr = [{ value: "年", child: years }, { value: "月", child: month }, { value: "日", child: day }] this.zdpdate = `20${this.years}-${this.month<10?'0'+this.month:this.month}-${this.day}` this.range = `20${this.years}-${this.month<10?'0'+this.month:this.month}-${this.day}` } else if (activeIdx == '月') { arr = [{ value: "年", child: years }, { value: "月", child: month }] // console.log(this.years,'年22'); this.zdpdate = `20${this.years}-${this.month<10?'0'+this.month:this.month}` this.range = getMonthStartEnd(this.zdpdate) } else if (activeIdx == '年') { arr = [{ value: "年", child: years }] this.zdpdate = `20${this.years}` this.range = `20${this.years}-1-31/20${this.years}-12-31` } else if (activeIdx == '周') { arr = [{ value: "年", child: years }, { value: "周", child: week }] this.zdpdate = `20${this.years}年 第${this.week}周` let wk = weekArr[this.week - 1] this.range = `${wk.year}-${wk.month}-${wk.date}` + '/' + `${wk.last.year}-${wk.last.month}-${wk.last.date}` } else if (activeIdx == '季') { arr = [{ value: "年", child: years }, { value: "季度", child: quarter }] this.zdpdate = `20${this.years}年 ${this.quarter}季度` let obj = getQuarterDates(`20${this.years}`, this.quarter) this.range = obj.startDate + '/' + obj.endDate } this.SelArr = arr }, open() { this.newDate() this.$refs.popup.open('bottom') }, close(num) { if (num == 1) { this.newDate() this.handleEmit() } else { this.handleEmit() } this.$refs.popup.close() }, handleEmit() { let { zdpdate, range, } = this this.$emit('submit-date', { zdpdate, range, type: this.activeIdx }) }, handleTabs(val) { this.activeIdx = val let { activeIdx, years, month, day, quarter, week } = this if (activeIdx == '日') { this.value = [years, month - 1, day - 1] } else if (activeIdx == '周') { this.value = [years, week - 1] } else if (activeIdx == '月') { this.value = [years, month - 1] } else if (activeIdx == '季') { this.value = [years, quarter - 1, ] } else if (activeIdx == '年') { this.value = [years] } console.log(this.value, '选择的日期'); this.initArr() }, // 选择器选择 handleChange(e) { let { value } = e.detail let { activeIdx } = this console.log(value); // 年小于前面+0 if (value[0] < 10) { value[0] = '0' + value[0] } this.years = value[0] if (activeIdx == '日') { this.month = value[1] + 1 //月 this.day = value[2] + 1 //日 } else if (activeIdx == '周') { this.week = value[1] + 1 //周 } else if (activeIdx == '季') { this.quarter = value[1] + 1 } else if (activeIdx == '月') { this.month = value[1] + 1 //月 } this.initArr() }, //获取当前月的天数 getMonthDays(year, month) { var thisDate = new Date(year, month, 0); return thisDate.getDate(); }, getYearWeek(endDate) { //本年的第一天 let beginDate = new Date(endDate.getFullYear(), 0, 1); //星期从0-6,0代表星期天,6代表星期六 let endWeek = endDate.getDay(); if (endWeek == 0) endWeek = 7; let beginWeek = beginDate.getDay(); if (beginWeek == 0) beginWeek = 7; //计算两个日期的天数差 let millisDiff = endDate.getTime() - beginDate.getTime(); let dayDiff = Math.floor((millisDiff + (beginWeek - endWeek) * (24 * 60 * 60 * 1000)) / 86400000); return Math.ceil(dayDiff / 7) + 1; }, handleQuarter(month) { const oneQuarter = [1, 2, 3] const twoQuarter = [4, 5, 6] const threeQuarter = [7, 8, 9] let num if (oneQuarter.includes(month)) { num = 1 } else if (twoQuarter.includes(month)) { num = 2 } else if (threeQuarter.includes(month)) { num = 3 } else { num = 4 } return num } } }</script><style lang="scss" scoped> * { box-sizing: border-box; } .zdp-pop { box-sizing: border-box; padding: 24rpx; width: 100%; height: 750rpx; background-color: #fff; .top-cont { height: 100rpx; display: flex; justify-content: space-between; align-items: center; margin-bottom: 32rpx; .close-cont { color: #aaa; letter-spacing: 6rpx; } .text-info { display: flex; flex-direction: column; align-items: center; } .save-cont { background: #409EFF; color: #fff; width: 100rpx; height: 60rpx; text-align: center; line-height: 60rpx; border-radius: 6rpx; } } .tabs-cont { box-sizing: border-box; height: 80rpx; background-color: #F3F5F9; display: flex; align-items: center; border-radius: 4rpx; padding: 0 10rpx; .tab-list { min-width: 20%; display: flex; height: 60%; flex: 1; justify-content: center; border-radius: 4rpx; &.active { background-color: #fff; } } } .date-cont { height: calc(750rpx - 180rpx); .picker-view { width: 100%; height: 100%; .item { display: flex; justify-content: center; align-items: center; } .uni-picker-view-indicator { height: 100rpx; } } } } </style>
utils文件
@/utils/getMonth.js
//获取这个月的月初和月末export function getMonthStartEnd(vars){ var str = ''; if(vars!=null&&vars!=''){ var nyYear=vars.slice(0,4); var nyMonth=vars.slice(5,vars.length); var firstDay = new Date(nyYear,nyMonth-1); var lastDay = new Date(new Date(nyYear,nyMonth).valueOf()-60*60*1000*24); function datasFormat(d){ var datetime=d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); return datetime; } str = datasFormat(firstDay) + "/" + datasFormat(lastDay) } return str}
@/utils/getQuarter.js
export function getQuarterDates(year, quarter) { const startDate = new Date(year, (quarter - 1) * 3, 1); const endDate = new Date(year, quarter * 3, 0); const startDay = startDate.getDate(); const endDay = endDate.getDate(); const startMonth = startDate.getMonth() + 1; const endMonth = endDate.getMonth() + 1; const startYear = startDate.getFullYear(); const endYear = endDate.getFullYear(); const startDateString = `${startYear}-${startMonth < 10 ? '0' + startMonth : startMonth}-${startDay < 10 ? '0' + startDay : startDay}`; const endDateString = `${endYear}-${endMonth < 10 ? '0' + endMonth : endMonth}-${endDay < 10 ? '0' + endDay : endDay}`; return { startDate: startDateString, endDate: endDateString };}// // 示例用法:计算2024年第2季度的起止日期// const quarterDates = getQuarterDates(2024,2);// console.log(quarterDates.startDate); // 输出:2024-04-01// console.log(quarterDates.endDate); // 输出:2024-06-30
@/utils/getWeek.js
//时间戳转年月日 参数是秒的时间戳 函数返回一个对象 对象里有年 月 日export function yearDay(long){ var time = new Date(long * 1000) var year = time.getFullYear(); var month = (time.getMonth()+1) < 10 ? '0' + (time.getMonth()+1) : (time.getMonth()+1); var date = time.getDate() < 10 ? '0' + time.getDate() : time.getDate() ; var yearday = {year,month,date} return yearday}//计算一年中的每一周都是从几号到几号//第一周为1月1日到 本年的 第一个周日//第二周为 本年的 第一个周一 往后推到周日//以此类推 再往后推52周。。。//如果最后一周在12月31日之前,则本年有垮了54周,反之53周//12月31 日不论是周几,都算为本周的最后一天//参数年份 ,函数返回一个数组,数组里的对象包含 这一周的开始日期和结束日期export function whichWeek(year){ var d = new Date(year, 0, 1); while (d.getDay() != 1) { d.setDate(d.getDate() + 1); } let arr = [] let longnum = d.setDate(d.getDate()) if(longnum > +new Date(year, 0, 1)){ let obj = yearDay(+new Date(year, 0, 1) / 1000) obj.last = yearDay( longnum / 1000 - 86400) arr.push(obj) } let oneitem = yearDay(longnum / 1000) oneitem.last = yearDay( longnum / 1000 + 86400 * 6) arr.push(oneitem) var lastStr for(var i = 0 ; i<51 ;i++){ let long = d.setDate(d.getDate() + 7) let obj = yearDay( long / 1000) obj.last = yearDay( long / 1000 + 86400 * 6) lastStr = long + 86400000 * 6 arr.push(obj) } if(lastStr < +new Date(year + 1, 0, 1)){ let obj = yearDay(lastStr / 1000 + 86400) obj.last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400) arr.push(obj) }else{ arr[arr.length-1].last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400) } return arr}// //例如 2012 年就跨了54周,也有很多是53周的// let week2012 = whichWeek(2012)// console.log(week2012)// //调用完得到的是一个数组见下图
uniapp使用插件使用
https://ext.dcloud.net.cn/plugin?id=16387https://ext.dcloud.net.cn/plugin?id=16387
zdp-date-picker使用说明
<zdp-date-picker ref="zdpdate" type="月" time="2023-2" @submit-date="handleDate($event)"></zdp-date-picker>
- 属性参数说明:
ref用于控制picker的弹出与隐藏,组件内有open和close函数
this.$refs.zdpdate.open()
参数名 | 作用 | 类型 | 默认值 |
type | 控制打开piker时tabs默认显示的位置 | String | 月 |
time | 显示的默认日期 | String | 2023-1 |
type用于控制打开piker时显示的tabs;默认参数:日、周、月、季、年
time用于控制显示的默认日期;
type=“日” time="2024-1-23" 代表默认显示日、time代表选中日期2024年1月23日
type=“周” time=“2024-4” 代表默认显示周、time代表选中日期2024年第4周
type=“月” time=“2024-1” 代表默认显示月、time代表选中日期2024年1月
type=“季” time=“2024-1” 代表默认显示季、time代表选中日期2024年第1季度
type=“年” time=“2024” 代表默认显示年、time代表选中日期2024
- 事件返回参数说明:
事件名 | 作用 |
submit-date | 用于接收组件返回的时间 |
submit-date 用于接收组件返回的时间
range 是选中日期的时间范围
zdpdate是具体的固定日期
type 是选中日期类型 日、周、月、季、年
handleDate(e){ let {range,zdpdate,type}=e this.range=range this.zdpdate=zdpdate this.type=type}
- 自定义插槽:
自定义显示组件内文本内容:
<zdp-date-picker ref="zdpdate" :type="type" time="2024-3" @submit-date="handleDate($event)"> <template #text="{scope}"> {{scope.range}} {{scope.zdpdate}} </template></zdp-date-picker>