因UI需求鴻蒙DatePicker不能取消循環(huán)問題,用TextPicker封裝了一個(gè)顯示年月日的時(shí)間控件。

import dayjs from "dayjs"
@Component
export struct CustomDatePicker {
? @Prop startDate:Date
? @Prop endDate:Date
? @Link selectedDate:Date
? @State generateYearMonth:TextCascadePickerRangeContent[] = []
? @State nums:number[] = []
? @State current:number[] = []
? disappearTextStyle:PickerTextStyle = {font:{size:16},color:$r('app.color.color_666666')}
? textStyle:PickerTextStyle = {font:{size:18},color:$r('app.color.color_333333')}
? selectedTextStyle:PickerTextStyle = {font:{size:20},color:$r('app.color.color_000000')}
? ///正常一個(gè)月有基本固定的天
? @State normal31Days:TextCascadePickerRangeContent[] = []
? @State normal30Days:TextCascadePickerRangeContent[] = []
? @State normal28Days:TextCascadePickerRangeContent[] = []
? @State normal29Days:TextCascadePickerRangeContent[] = []
? //平年、閏年
? @State normalOneMoths:TextCascadePickerRangeContent[] = []
? @State normalTwoMoths:TextCascadePickerRangeContent[] = []
? //得到固定的月信息
? getMonthsWithYear(year:number){
? ? let daysInMonth = new Date(year,2,0).getDate()
? ? let? months : TextCascadePickerRangeContent[] = []
? ? if (daysInMonth === 28) { //平年
? ? ? if (this.normalOneMoths.length === 12) {
? ? ? ? return this.normalOneMoths
? ? ? }
? ? }else { //閏年
? ? ? if (this.normalTwoMoths.length === 12) {
? ? ? ? return this.normalTwoMoths
? ? ? }
}
? ? for (let month = 1; month <= 12 ; month++) {
? ? ? let? days = this.getDaysWithMonth(year,month)
? ? ? if (days.length>0) {
? ? ? ? months.push({text:`${month.toString().padStart(2,'0')}月`,children:days})
? ? ? }
}
? ? if (daysInMonth === 28) { //平年
? ? ? this.normalOneMoths = months
? ? }else {
? ? ? this.normalTwoMoths = months
? ? }
? ? return months
? }
? //得到固定的天
? getDaysWithMonth(year:number,month:number){
? ? let? days : TextCascadePickerRangeContent[] = []
? ? /// 計(jì)算每個(gè)月的天數(shù)
? ? let daysInMonth = new Date(year,month,0).getDate()
? ? if (daysInMonth === 31) {
? ? ? if (this.normal31Days.length !== 31) {
? ? ? ? for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? }
? ? ? ? this.normal31Days = days
? ? ? }else {
? ? ? ? days = this.normal31Days
? ? ? }
? ? }else if (daysInMonth === 30){
? ? ? if (this.normal30Days.length !== 30) {
? ? ? ? for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? }
? ? ? ? this.normal30Days = days
? ? ? }else {
? ? ? ? days = this.normal30Days
? ? ? }
? ? }else if (daysInMonth === 29){
? ? ? if (this.normal29Days.length !== 30) {
? ? ? ? for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? }
? ? ? ? this.normal29Days = days
? ? ? }else {
? ? ? ? days = this.normal29Days
? ? ? }
? ? }else if (daysInMonth === 28){
? ? ? if (this.normal28Days.length !== 30) {
? ? ? ? for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? }
? ? ? ? this.normal28Days = days
? ? ? }else {
? ? ? ? days = this.normal28Days
? ? ? }
? ? }else {
? ? ? for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? }
}
? ? return days
? }
? generateYearMonthRange(start:Date,end:Date){
? ? const range:TextCascadePickerRangeContent[] = []
? ? let startYear = start.getFullYear()
? ? let endYear = end.getFullYear()
? ? let startMonth = start.getMonth() + 1
? ? let endMonth = end.getMonth()+ 1
? ? let startDay = start.getDate()
? ? let endDay = end.getDate()
? ? for (let year = startYear; year <= endYear; year++) {
? ? ? let? months : TextCascadePickerRangeContent[] = []
? ? ? if (startYear === endYear){
? ? ? ? for (let month = startMonth; month <= endMonth ; month++) {
? ? ? ? ? let? days : TextCascadePickerRangeContent[] = []
? ? ? ? ? /// 計(jì)算每個(gè)月的天數(shù)
? ? ? ? ? let daysInMonth = new Date(year,month,0).getDate()
? ? ? ? ? if (startMonth === endMonth) {
? ? ? ? ? ? for (let day = startDay; day <= endDay; day++) {
? ? ? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? ? ? }
? ? ? ? ? }else if (month === startMonth) {
? ? ? ? ? ? for (let day = startDay; day <= daysInMonth; day++) {
? ? ? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? ? ? }
? ? ? ? ? }else if (month === endMonth) {
? ? ? ? ? ? for (let day = 1; day <= endDay; day++) {
? ? ? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? ? ? }
? ? ? ? ? }else {
? ? ? ? ? ? days = this.getDaysWithMonth(year,month)
? ? ? ? ? ? // for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? ? //? days.push({text:`${day.toString().padStart(2,'0')}日`})
// }
? ? ? ? ? }
? ? ? ? ? if (days.length>0) {
? ? ? ? ? ? months.push({text:`${month.toString().padStart(2,'0')}月`,children:days})
? ? ? ? ? }
}
? ? ? } else? if (year === startYear) {
? ? ? ? for (let month = startMonth; month <= 12 ; month++) {
? ? ? ? ? let? days : TextCascadePickerRangeContent[] = []
? ? ? ? ? /// 計(jì)算每個(gè)月的天數(shù)
? ? ? ? ? let daysInMonth = new Date(year,month,0).getDate()
? ? ? ? ? if (month === startMonth) {
? ? ? ? ? ? for (let day = startDay; day <= daysInMonth; day++) {
? ? ? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? ? ? }
? ? ? ? ? }else {
? ? ? ? ? ? days = this.getDaysWithMonth(year,month)
? ? ? ? ? ? // for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? ? //? days.push({text:`${day.toString().padStart(2,'0')}日`})
// }
? ? ? ? ? }
? ? ? ? ? if (days.length>0) {
? ? ? ? ? ? months.push({text:`${month.toString().padStart(2,'0')}月`,children:days})
? ? ? ? ? }
}
? ? ? }else if (year === endYear){
? ? ? ? for (let month = 1; month <= endMonth ; month++) {
? ? ? ? ? let? days : TextCascadePickerRangeContent[] = []
? ? ? ? ? /// 計(jì)算每個(gè)月的天數(shù)
? ? ? ? ? let daysInMonth = new Date(year,month,0).getDate()
? ? ? ? ? if (month === endMonth) {
? ? ? ? ? ? for (let day = 1; day <= endDay; day++) {
? ? ? ? ? ? ? days.push({text:`${day.toString().padStart(2,'0')}日`})
? ? ? ? ? ? }
? ? ? ? ? }else {
? ? ? ? ? ? days = this.getDaysWithMonth(year,month)
? ? ? ? ? ? // for (let day = 1; day <= daysInMonth; day++) {
? ? ? ? ? ? //? days.push({text:`${day.toString().padStart(2,'0')}日`})
// }
? ? ? ? ? }
? ? ? ? ? if (days.length>0) {
? ? ? ? ? ? months.push({text:`${month.toString().padStart(2,'0')}月`,children:days})
? ? ? ? ? }
}
? ? ? }else {
? ? ? ? months = this.getMonthsWithYear(year)
? ? ? }
? ? ? if (months.length>0) {
? ? ? ? range.push({
? ? ? ? ? text:`${year}年`,
? ? ? ? ? children:months
? ? ? ? })
? ? ? }
}
? ? return range
? }
? aboutToAppear(): void {
? ? ? this.generateYearMonth = this.generateYearMonthRange(this.startDate,this.endDate)
? ? ? let selectedYear = this.selectedDate.getFullYear()
? ? ? let selectedMonth = this.selectedDate.getMonth() +1
? ? ? let selectedDay = this.selectedDate.getDate()
? ? let nums:number[] = []
? ? for (let index = 0; index < this.generateYearMonth.length; index++) {
? ? ? const years = this.generateYearMonth[index];
? ? ? if (years.text == `${selectedYear.toString()}年`) {
? ? ? ? nums.push(index)
? ? ? ? if (years.children) {
? ? ? ? ? for (let index = 0; index < years.children.length; index++) {
? ? ? ? ? ? const months = years.children[index];
? ? ? ? ? ? if (months.text == `${selectedMonth.toString().padStart(2,'0')}月`) {
? ? ? ? ? ? ? nums.push(index)
? ? ? ? ? ? ? if (months.children) {
? ? ? ? ? ? ? ? for (let index = 0; index < months.children.length; index++){
? ? ? ? ? ? ? ? ? const days = months.children[index];
? ? ? ? ? ? ? ? ? if (days.text == `${selectedDay.toString().padStart(2,'0')}日`) {
? ? ? ? ? ? ? ? ? ? nums.push(index)
? ? ? ? ? ? ? ? ? ? break
? ? ? ? ? ? ? ? ? }
}
}
}
}
}
}
}
? ? this.nums = nums
? }
? build() {
? ? TextPicker({range:this.generateYearMonth,selected:this.nums})
? ? ? .disappearTextStyle(this.disappearTextStyle)
? ? ? .textStyle(this.textStyle)
? ? ? .selectedTextStyle(this.selectedTextStyle)
? ? ? .canLoop(false)
? ? ? .onChange((value: string | string[], index: number | number[])=>{
? ? ? ? if (typeof index === 'object') {
? ? ? ? ? ? let year = index[0]
? ? ? ? ? ? let month = index[1]
? ? ? ? ? if (this.nums[0] !== year){
? ? ? ? ? ? let currentYear =? this.generateYearMonth[year]
? ? ? ? ? ? if (!currentYear.children) return
? ? ? ? ? ? if (currentYear.children.length <= this.nums[1]) {
? ? ? ? ? ? ? let currentMonth = currentYear.children[currentYear.children.length-1]
? ? ? ? ? ? ? if (!currentMonth.children) return
? ? ? ? ? ? ? if (currentMonth.children.length <= this.nums[2]) {
? ? ? ? ? ? ? ? this.nums = [year,currentYear.children.length-1,currentMonth.children.length-1]
? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? this.nums = [year,currentYear.children.length-1,this.nums[2]]
? ? ? ? ? ? ? }
? ? ? ? ? ? }else {
? ? ? ? ? ? ? let currentMonth = currentYear.children[this.nums[1]]
? ? ? ? ? ? ? if (!currentMonth.children) return
? ? ? ? ? ? ? if (currentMonth.children.length <= this.nums[2]) {
? ? ? ? ? ? ? ? this.nums = [year,this.nums[1],currentMonth.children.length-1]
? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? this.nums = [year,this.nums[1],this.nums[2]]
? ? ? ? ? ? ? }
}
}
? ? ? ? ? else if (this.nums[1]!== month){
? ? ? ? ? ? let currentYear =? this.generateYearMonth[year]
? ? ? ? ? ? if (!currentYear.children) return
? ? ? ? ? ? let currentMonth = currentYear.children[month]
? ? ? ? ? ? if (!currentMonth.children) return
? ? ? ? ? ? if (currentMonth.children.length <= this.nums[2]) {
? ? ? ? ? ? ? this.nums = [this.nums[0],index[1],currentMonth.children.length-1]
? ? ? ? ? ? }else {
? ? ? ? ? ? ? this.nums = [this.nums[0],index[1],this.nums[2]]
? ? ? ? ? ? }
? ? ? ? ? }else if (this.nums[2] !== index[2]){
? ? ? ? ? ? this.nums = [this.nums[0],this.nums[1],index[2]]
? ? ? ? ? }
}
? ? ? ? let year = this.generateYearMonth[this.nums[0]]
? ? ? ? if (!year.children)return
? ? ? ? let month = year.children[this.nums[1]]
? ? ? ? if (!month.children)return
? ? ? ? let day = month.children[this.nums[2]]
? ? ? ? this.selectedDate = dayjs(`${(year.text as string).replace('年','')}${(month.text as string).replace('月','')}${(day.text as string).replace('日','')}`).toDate()//dayjs(`${year.text}${month.text}${day.text}`).toDate()
? ? ? })
? }
}