uviewplus中的时间单选框up-datetime-picker的使用方法
前言
在实际开发中,我们经常需要使用时间选择器来让用户选择特定的时间。本文将详细介绍uviewplus中up-datetime-picker组件的使用方法,特别是在处理年月选择时的一些关键实现,因为官方有很多相关的功能和方法在文档中没有说明清楚,所以我做了许多调试,终于完成了。
基础使用
1. 组件引入
<template><view class="datetime-picker-container"><view class="picker-wrapper" @click="openPicker"><text class="picker-label">选择日期:</text><view class="picker-input">{{getTimeYearAndMouth(yearMonth)}}</view></view><up-datetime-pickerv-if="selectTimeStampList.length > 0"v-model="yearMonth"mode="year-month":show="timeSelectShow":formatter="formatter":filter="filterTime"format="YYYY-MM"@cancel="cancelPicker"@confirm="confirmPicker"/></view>
</template>
2. 基础数据定义
// 当前选中的时间戳
const yearMonth = ref(Date.now())
// 控制选择器显示/隐藏
const timeSelectShow = ref(false)
// 可选时间戳列表
const selectTimeStampList = reactive<number[]>([])
// 年份去重数组 - 关键数据结构
const fitterTheSameYears = reactive<number[]>([])
核心实现
1. 时间映射表
// 创建一个 Map 来存储有效的年月组合
const validDateMap = computed(() => {const dateMap = new Map()if (!selectTimeStampList?.length) {return dateMap}selectTimeStampList.forEach(timestamp => {const date = new Date(timestamp)const year = date.getFullYear()const month = date.getMonth() + 1if (!dateMap.has(year)) {dateMap.set(year, new Set())}dateMap.get(year).add(month)})return dateMap
})
2. 格式化器实现
重点,如果没有按照规范过滤的话会产生一系列问题。
const formatter = (type: string, value: number) => {// 处理特殊情况,当切换年月份的时候最后会传进两个被选择的参数,所以需要处理 [2024, 01] 的情况if (value.toString().length < 5){if (type === 'year') {return `${value}年`}if (type === 'month') {fitterTheSameYears.length = 0 // 重要: 清空年份数组// 判断月份字符串是否以 0 开头,如果是的话,则取第二个字符,否则取整个字符串 ,因为这样的格式才能正常选中return value.startsWith('0') ? `${value[1]}月` : `${value}月`}}// 基础类型检查if (!value || typeof value !== 'number') {return ''}const date = new Date(value)const year = date.getFullYear()const month = date.getMonth() + 1if (type === 'year') {if (!validDateMap.value.size) {return `${year}年`}// 检查是否是有效年份并去重if (validDateMap.value.has(year) && !fitterTheSameYears.includes(year)) {fitterTheSameYears.push(year)return `${year}年`}return null}if (type === 'month') {if (!validDateMap.value.size) {return `${month}月`}// 检查当前年份下的月份是否有效const currentYear = new Date(yearMonth.value || Date.now()).getFullYear()const validMonths = validDateMap.value.get(currentYear)if (validMonths && validMonths.has(month)) {return `${month}月`}return null}return value.toString()
}
3. 事件处理方法
// 打开选择器
const openPicker = () => {timeSelectShow.value = true
}// 格式化显示时间
const getTimeYearAndMouth = (timestamp: number) => {const date = new Date(timestamp)return `${date.getFullYear()}年${date.getMonth() + 1}月`
}// 确认选择
const confirmPicker = (data) => {yearMonth.value = data.valuetimeSelectShow.value = false// 这里可以添加选择后的业务处理逻辑
}// 取消选择
const cancelPicker = () => {timeSelectShow.value = false
}
重要说明
1. fitterTheSameYears的作用
- 用于存储已处理的年份,防止重复显示
- 在切换到月份选择时需要清空
- 确保年份选项的唯一性
2. formatter函数的关键点
- 需要处理特殊的数值情况
- 年份和月份的显示格式化
- 配合fitterTheSameYears进行年份去重
- 根据validDateMap过滤无效选项
3. 时间选择的注意事项
- 切换年份时会影响可选月份
- 确保时间戳格式统一
- 处理无数据的边界情况
常见问题
1. 无法切换年份或月份
可能的原因:
- formatter返回值不正确
- fitterTheSameYears未正确维护
- validDateMap数据异常
解决方案:
- 检查formatter的返回值
- 确保在适当时机清空fitterTheSameYears
- 验证时间戳列表的正确性
2. 显示异常
可能的原因:
- 时间戳格式不统一
- 特殊数值处理不当
- v-if条件判断有误
解决方案:
- 统一使用毫秒级时间戳
- 完善特殊情况的处理
- 检查组件显示条件
最佳实践
- 数据初始化
- 确保selectTimeStampList在使用前已正确初始化
- 使用reactive而不是ref定义数组
- 注意时间戳格式的统一性
- 性能优化
- 使用computed缓存validDateMap
- 避免在formatter中进行复杂计算
- 合理使用v-if控制组件渲染
- 用户体验
- 提供清晰的时间选择提示
- 处理好加载状态
- 确保选择器操作流畅