当前位置: 首页 > article >正文

uviewplus中的时间单选框up-datetime-picker的在uni-app+vue3的使用方法

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-picker
      v-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() + 1

    if (!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() + 1

  if (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.value
  timeSelectShow.value = false
  // 这里可以添加选择后的业务处理逻辑
}

// 取消选择
const cancelPicker = () => {
  timeSelectShow.value = false
}

重要说明

1. fitterTheSameYears的作用

  • 用于存储已处理的年份,防止重复显示
  • 在切换到月份选择时需要清空
  • 确保年份选项的唯一性

2. formatter函数的关键点

  • 需要处理特殊的数值情况
  • 年份和月份的显示格式化
  • 配合fitterTheSameYears进行年份去重
  • 根据validDateMap过滤无效选项

3. 时间选择的注意事项

  • 切换年份时会影响可选月份
  • 确保时间戳格式统一
  • 处理无数据的边界情况

常见问题

1. 无法切换年份或月份

可能的原因:

  • formatter返回值不正确
  • fitterTheSameYears未正确维护
  • validDateMap数据异常

解决方案:

  • 检查formatter的返回值
  • 确保在适当时机清空fitterTheSameYears
  • 验证时间戳列表的正确性

2. 显示异常

可能的原因:

  • 时间戳格式不统一
  • 特殊数值处理不当
  • v-if条件判断有误

解决方案:

  • 统一使用毫秒级时间戳
  • 完善特殊情况的处理
  • 检查组件显示条件

最佳实践

  1. 数据初始化
  • 确保selectTimeStampList在使用前已正确初始化
  • 使用reactive而不是ref定义数组
  • 注意时间戳格式的统一性
  1. 性能优化
  • 使用computed缓存validDateMap
  • 避免在formatter中进行复杂计算
  • 合理使用v-if控制组件渲染
  1. 用户体验
  • 提供清晰的时间选择提示
  • 处理好加载状态
  • 确保选择器操作流畅

http://www.kler.cn/a/429777.html

相关文章:

  • Mysql--基础篇--多表查询(JOIN,笛卡尔积)
  • 某地武警海警总队建筑物自动化监测
  • 专题 - STM32
  • Jenkins内修改allure报告名称
  • 企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布
  • php 使用simplexml_load_string转换xml数据格式失败
  • 新手前端开发入职公司全流程
  • 使用wpa_cli调用接口报错failed opendir
  • 洛谷 B3854 [语言月赛 202309] 数组与内存 EV C语言
  • 将setkey工具从freeBSD移植到rtems-libbsd
  • SRS 服务器入门:实时流媒体传输的理想选择
  • 基于vpk180边缘场景下分布式神经网络训练模型部署
  • 医院远程诊断管理系统|Java|SSM|JSP| 前后端分离
  • 发布订阅者=>fiber=>虚拟dom
  • 【AI】Jetson Nano中安装DeepStream
  • MySQL生产环境备份脚本
  • 【JavaWeb后端学习笔记】登录校验(JWT令牌技术、Interceptor拦截器、Filter过滤器)
  • 学生信息管理系统(简化版)数据库部分
  • 基于公网的无线全双工内部通话系统在演出行业可以用吗?
  • 纯虚函数和抽象类在面向对象编程中的意义
  • 【机器学习】基础知识:SSR-残差平方和(Sum of Squared Residuals)
  • 能源变革,分布式光伏与储能协调控制
  • socket UDP 环路回显的服务端
  • OPC UA 客户端开发工具,模拟器,可视化GUI
  • HarmonyOS-高级(一)
  • 使用 `typing_extensions.TypeAlias` 简化类型定义:初学者指南