合肥序曲网站建设公司怎么样,软件定制解决方案,上海房产交易网站,wordpress 如何移动端vue3ts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及单列选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件(全局自动导入的情况) 3.注意事项3.1refSelectDialog3.1 backgroundColor#fffts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及单列选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件(全局自动导入的情况) 3.注意事项3.1refSelectDialog3.1 backgroundColor#fff 圆角问题 (已优化) 自我记录 1.先上效果图 直接上代码
2.代码展示
2.1 组件
src\components\hbcy-popup.vue
script setup langts
import type { Item, PopupType } from /types/addInfo
import { formatDate, parseDate } from /utils
import { onMounted } from vue
import { ref } from vueconst props defineProps{popupTitle: stringtype: PopupTypedata?: Item[] // 展示数据ListselectData: string | number // 默认显示 2023-8-24 || 0
}()
const emit defineEmits{(e: confirm-popup, params: string | number): void(e: close-popup): void
}()// 创建选择区间 参考uni文档
const date new Date()
// 年月日
const TYPEYY_MM_DD props.type year || props.type month || props.type day
// 月日
const TYPEMM_DD props.type month || props.type day
const TYPEYY props.type year
const TYPEMM props.type month
const TYPEDD props.type day
const TYPESingle props.type single
const years TYPEYY_MM_DD? Array.from({ length: date.getFullYear() - 1989 }, (_, index) 1990 index): []
const months TYPEMM_DD ? Array.from({ length: 12 }, (_, index) index 1) : []
const days TYPEDD ? Array.from({ length: 31 }, (_, index) index 1) : []
// 处理默认展示的时间
const defaultDate TYPEYY_MM_DD ? parseDate(props.selectData as string, props.type) : []
// 单列数据
const singleList ref(TYPESingle ? props.data : [])
const singleSelect refnumber((props.selectData as number) || 0)
// 确保默认时间
const year refnumber(defaultDate[0])
const month refnumber | undefined(defaultDate[1])
const day refnumber | undefined(defaultDate[2])
// 区分日期展示
let showValueList: number[] []
// 展示日期的选中时间
if (TYPEDD) {showValueList [years.indexOf(defaultDate[0]),months.indexOf(defaultDate[1]!),days.indexOf(defaultDate[2]!),]
} else if (TYPEMM) {showValueList [years.indexOf(defaultDate[0]), months.indexOf(defaultDate[1]!)]
} else if (TYPEYY) {showValueList [years.indexOf(defaultDate[0])]
} else if (TYPESingle) {showValueList [singleSelect.value]
}
const valueList refnumber[]()
onMounted(() {// 确保回显的value 在 页面渲染之后valueList.value showValueList
})// 切换事件
const bindChange: UniHelper.PickerViewOnChange (e) {const val e.detail.valueif (TYPEYY_MM_DD) {year.value years[val[0]]month.value months[val[1]]day.value days[val[2]]} else {// 单列singleSelect.value val[0]}
}
// 确定按钮
const onClickConfirmPopup (): void {if (TYPEYY_MM_DD) {emit(confirm-popup, formatDate(year.value, month.value, day.value))} else {// 单列emit(confirm-popup, singleSelect.value)}onClosePopup()
}
// 关闭弹出层
const onClosePopup (): void {emit(close-popup)
}
const { safeAreaInsets } uni.getSystemInfoSync()
/scripttemplateview classselectBoxview classselectTitletext classcancel clickonClosePopup取消/texttext classtitle{{ 选择 popupTitle }}/texttext classcancel ok clickonClickConfirmPopup确定/text/viewblock v-ifTYPEYY_MM_DDpicker-view:immediate-changetrueindicator-classindicatorClass:valuevalueListchangebindChangeclasspicker-viewpicker-view-columnview classitem v-for(item, index) in years :keyindex{{ item }}年/view/picker-view-columnpicker-view-column v-ifTYPEMM_DDview classitem v-for(item, index) in months :keyindex{{ item }}月/view/picker-view-columnpicker-view-column v-ifTYPEDDview classitem v-for(item, index) in days :keyindex{{ item }}日/view/picker-view-column/picker-view/block!-- TODO --block v-elsepicker-view:immediate-changetrueindicator-classindicatorClass:valuevalueListchangebindChangeclasspicker-viewpicker-view-columnview classitem v-foritem in singleList :keyitem.key{{ item.value }}/view/picker-view-column/picker-view/block!-- 修复启用:safeAreatrue 时 圆角不好实现问题,现在是自己做的适配--view :style{ height: safeAreaInsets?.bottom px } stylewidth: 100% //view
/templatestyle langscss scoped
::v-deep.indicatorClass {height: 100rpx;
}
.picker-view {width: 750rpx;height: 500rpx;margin-top: 20rpx;
}
.item {line-height: 100rpx;text-align: center;
}
.selectBox {width: 100%;height: fit-content;background-color: #fff;border-radius: 20rpx 20rpx 0 0;.selectTitle {display: flex;justify-content: space-between;align-items: center;height: 100rpx;font-size: 32rpx;.title {font-size: 32rpx;}.cancel {width: 160rpx;text-align: center;color: #ff976a;font-size: 32rpx;}.ok {font-size: 32rpx;color: #07c160;}}
}
/style2.2 公共方法处理日期
src\utils\index.ts
// 将 yyyy-mm-dd 的字符串 2023-08-24 [2023,8,24] || [2023,8] || [2023]
export function parseDate(dateString: string, type: string): [number, number?, number?] {const date dateString ? new Date(dateString) : new Date()const year date.getFullYear()const month type day || type month ? date.getMonth() 1 : undefinedconst day type day ? date.getDate() : undefinedreturn [year, month, day]
}// 将数字格式的年、月、日转换成格式为 yyyy-mm-dd 的字符串 || yyyy-mm || yyyy
export function formatDate(year: number, month?: number, day?: number): string {const formattedMonth month ! undefined ? (month 10 ? 0${month} : ${month}) : const formattedDay day ! undefined ? (day 10 ? 0${day} : ${day}) : return ${year}${formattedMonth ? -${formattedMonth} : }${formattedDay ? -${formattedDay} : }
}
// 获取当前年月日并返回yyyy-mm-dd格式
export function getCurrentDate(): string {const currentDate new Date()const year currentDate.getFullYear()const month (currentDate.getMonth() 1).toString().padStart(2, 0)const day currentDate.getDate().toString().padStart(2, 0)return ${year}-${month}-${day}
}2.3 使用组件(全局自动导入的情况)
全局自动导入看(https://blog.csdn.net/zhgweb/article/details/132499886?spm1001.2014.3001.5502 第11标题 没有配置全局自动导入的需要自己手动引入! src\pages\test\index.vue
script setup langts
import type { Ref } from vue
import { ref } from vue
import { getCurrentDate } from /utils
type Item {key: number | stringvalue: string
}// 日期相关
const isShowPopop ref(false)
// 弹出层实例
const refSelectDialog: RefUniHelper.UniPopup | null ref(null)
const dateTime ref(getCurrentDate()) // 默认显示当前时间
// 单列相关
let list [{ key: 1, value: 最高 },{ key: 2, value: 最低 },{ key: 3, value: 自定义 },
]
const singleList refItem[](list)
const singleSelect ref(0)
const isShowSingPopop ref(false)
const selectItem refItem(singleList.value[singleSelect.value]) // 默认选中// 打开日期弹窗 or 单列
const onClickPopup (type?: string) {refSelectDialog.value!.open()if (type single) {isShowSingPopop.value true} else {isShowPopop.value true}
}
// 关闭弹窗
const onClosePopup () {refSelectDialog.value!.close()isShowPopop.value falseisShowSingPopop.value false
}
// 确定日期弹窗
const onConfirmPopup (val: string | number, type: string) {if (type single) {singleSelect.value val as numberselectItem.value singleList.value[singleSelect.value]console.log(selectItem.value, singleSelect)} else {dateTime.value val as stringconsole.log(dateTime.value, dateTime.value)}
}
/scripttemplateview classtest-page!-- 使用组件 --uni-popuprefrefSelectDialogtypebottom:maskClickfalse:isMaskClickfalse:safeAreafalse:closeonClosePopuphbcy-popupv-ifisShowPopoppopup-title日期typeday:select-datadateTimeconfirm-popuponConfirmPopup($event, dateTime)close-popuponClosePopup/hbcy-popupv-ifisShowSingPopoppopup-title社保基数typesingle:datasingleList:select-datasingleSelectconfirm-popuponConfirmPopup($event, single)close-popuponClosePopup//uni-popup/view
/templatestyle langscss scoped
.test-page {.item-date {width: 300rpx;height: 60rpx;line-height: 60rpx;text-align: center;border: 1rpx solid #999;font-size: 28rpx;-placeholder {color: #999;}-txt {color: #333;}}
}
/style3.注意事项
3.1refSelectDialog
// 弹出层实例
const refSelectDialog: RefUniHelper.UniPopup | null ref(null)ts类型有一些问题,找了好久不知道该给什么类型!!! 新手TS,有大佬的话请指出,感谢!
3.1 backgroundColor#fff 圆角问题 (已优化)
uni-popup backgroundColor#fff / // 可以不加了因为默认是开启适配的,需要加上背景色,否则就是透明的底部区域示例如下:源码查看 整理不易,如有转载请备注原文地址!