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

【前端开发】Uniapp日期时间选择器:实现分钟动态步长设置

技术栈

  • Uniapp + Vue3 + uView
  • 年份显示前后一年,分钟动态设置间隔

效果图

在这里插入图片描述

  1. 主体显示
    <view class="uni-row-between selector"><view class="uni-flex-1 left" @click="!props.disabled && openPicker()"><uni-iconscolor="#c0c4cc"type="calendar"size="22"style="position: relative; top: 1px"></uni-icons><text class="label">{{ displayValue || placeholder }}</text></view><uni-iconscolor="#c0c4cc"type="clear"size="22"style="position: relative; top: 1px"v-if="!props.disabled && localValue"@click="clear"></uni-icons></view>
  1. 底部弹窗
        <transition name="fade"><view v-if="showPicker" class="overlay" @click="closePicker"></view><view v-if="showPicker" class="picker-modal"><view class="title">{{ placeholder }}</view><view class="uni-row tab-container"><view:class="['tab', activeTab === 'date' ? 'active' : '']"@click="switchTab('date')">选择日期</view><view:class="['tab', activeTab === 'time' ? 'active' : '']"@click="switchTab('time')":style="{pointerEvents: dateConfirmed ? 'auto' : 'none',}">选择时间</view></view><picker-viewv-show="activeTab === 'date'"class="picker-view":indicator-style="'height: 50px;'":value="[yearIndex, monthIndex, dayIndex]"@change="onDateChange"><picker-view-column><view v-for="(y, i) in years" :key="i" class="picker-item">{{ y }}</view></picker-view-column><picker-view-column><view v-for="(m, i) in months" :key="i" class="picker-item">{{ m }}</view></picker-view-column><picker-view-column><view v-for="(d, i) in days" :key="i" class="picker-item">{{ d }}</view></picker-view-column></picker-view><picker-viewv-show="activeTab === 'time'"class="picker-view":indicator-style="'height: 50px;'":value="[hourIndex, minuteIndex]"@change="onTimeChange"><picker-view-column><view v-for="(h, i) in hours" :key="i" class="picker-item">{{ h }}</view></picker-view-column><picker-view-column><view v-for="(m, i) in minutes" :key="i" class="picker-item">{{ m }}</view></picker-view-column></picker-view><view class="picker-footer"><buttonv-if="activeTab === 'date'"class="btn-next"@click="goToTime">下一步</button><button v-else class="btn-confirm" @click="confirm">确定</button></view><view class="close-btn" @click="closePicker"></view></view></transition>
  1. 组件抛出
const props = defineProps({modelValue: {type: String,default: "",},placeholder: {type: String,default: "请选择时间",},minuteStep: {type: Number,default: 1,},disabled: {type: Boolean,default: false,},
});const localValue = ref(props.modelValue);
watch(() => props.modelValue,(newVal) => {localValue.value = newVal;}
);
const emit = defineEmits(["update:modelValue"]);
  1. 年月列表项和默认值
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.getMonth() + 1;// 年份只显示3年
const years = [currentYear - 1, currentYear, currentYear + 1];
const months = Array.from({ length: 12 }, (_, i) => i + 1);// 默认选中Index
const yearIndex = ref(1);
const monthIndex = ref(currentMonth - 1);
  1. 时分列表项和默认值
const currentHour = now.getHours();
const currentMinute = now.getMinutes();const hours = Array.from({ length: 24 }, (_, i) => i);
const minutes = computed(() => {const step = props.minuteStep;return Array.from({ length: Math.floor(60 / step) }, (_, i) => i * step);
});// 默认选中Index
const hourIndex = ref(currentHour);
const minuteIndex = ref(Math.floor(currentMinute / props.minuteStep));
  1. 监听年月变化,更新天数
// 默认选中Index
const dayIndex = ref(currentDay - 1);
// 计算天数
const updateDays = () => {const y = years[yearIndex.value];const m = months[monthIndex.value];const dayCount = new Date(y, m, 0).getDate();days.value = Array.from({ length: dayCount }, (_, i) => i + 1);if (dayIndex.value >= dayCount) {dayIndex.value = dayCount - 1;}
};// 监听年月变化,更新天数
watch([yearIndex, monthIndex], updateDays);
  1. 初始化当天日期时间
onMounted(() => {updateDays();// 初始化选中项if (localValue.value) {const reg = /(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{1,2})时(\d{1,2})分/;const matched = localValue.value.match(reg);if (matched) {const [_, y, mo, d, h, mi] = matched;const yNum = +y,moNum = +mo,dNum = +d,hNum = +h,miNum = +mi;const yi = years.indexOf(yNum);yearIndex.value = yi !== -1 ? yi : 1;monthIndex.value = moNum - 1;dayIndex.value = dNum - 1;hourIndex.value = hNum;minuteIndex.value = Math.floor(miNum / props.minuteStep);updateDays();}}
});
  1. 选项变化更新对应值
const onDateChange = (e) => {const [y, m, d] = e.detail.value;yearIndex.value = y;monthIndex.value = m;dayIndex.value = d;updateDays();
};const onTimeChange = (e) => {const [h, mm] = e.detail.value;hourIndex.value = h;minuteIndex.value = mm;
};
  1. 确定事件,抛出最新值
const confirm = () => {const y = years[yearIndex.value];const m = String(months[monthIndex.value]).padStart(2, "0");const d = String(days.value[dayIndex.value]).padStart(2, "0");const h = String(hours[hourIndex.value]).padStart(2, "0");const mm = String(minutes.value[minuteIndex.value]).padStart(2, "0");const val = `${y}-${m}-${d} ${h}:${mm}`;emit("update:modelValue", val);localValue.value = val;showPicker.value = false;
};
  1. 组件样式
<style lang="scss" scoped>
.time-box {width: 100%;.selector {width: 100%;border: 1px solid #eee;border-radius: 10rpx;padding: 0 24rpx;height: 70rpx;font-size: 0.32rem;color: #999;justify-content: flex-start;.label {margin-left: 15rpx;}}.overlay {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.5);z-index: 998;}.picker-modal {position: fixed;bottom: 0;left: 0;right: 0;background: #fff;border-top-left-radius: $border-radius;border-top-right-radius: $border-radius;box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);z-index: 999;padding-bottom: 40rpx;.title {font-weight: bold;text-align: center;font-size: 0.32rem;line-height: 110rpx;}.tab-container {border-bottom: 1px solid #eee;.tab {flex: 1;text-align: center;font-size: 0.32rem;padding: 20rpx 0;color: #999;position: relative;&.active {color: $primary-color;font-weight: bold;&::after {content: "";position: absolute;bottom: -1px;left: 30%;right: 30%;height: 2px;background-color: $primary-color;}}}}.picker-view {background: $background-color;height: 400rpx;.picker-item {height: 100rpx;line-height: 100rpx;text-align: center;font-size: 0.34rem;color: #333;}}.picker-footer {padding: 32rpx 24px;border-top: 1px solid #eee;.btn-next,.btn-confirm {width: 100%;background-color: $primary-color;border: none;border-radius: $border-radius;color: #fff;font-size: 0.36rem;}}.close-btn {position: absolute;top: 20rpx;right: 40rpx;font-size: 0.4rem;cursor: pointer;color: #999;}}
}
.fade-enter-active,
.fade-leave-active {transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {opacity: 0;
}
.fade-enter-to,
.fade-leave-from {opacity: 1;
}
</style>
  1. 注册组件进行调用
import DateTimePicker from "@/components/date-time-picker";
app.component("DateTimePicker", DateTimePicker);<DateTimePickerstyle="width: 100%":modelValue="data.applyForm.DateTime":minute-step="10"@update:modelValue="getChangeItemValue"/>

相关文章:

【前端开发】Uniapp日期时间选择器:实现分钟动态步长设置

技术栈 Uniapp Vue3 uView年份显示前后一年&#xff0c;分钟动态设置间隔 效果图 主体显示 <view class"uni-row-between selector"><view class"uni-flex-1 left" click"!props.disabled && openPicker()"><uni-icons…...

跑通Multi-Agent-Constrained-Policy-Optimisation

✅ 1. 克隆项目并创建 Conda 环境 git clone https://github.com/chauncygu/Multi-Agent-Constrained-Policy-Optimisation.git cd Multi-Agent-Constrained-Policy-Optimisation conda create --prefix ./envs python3.7 -y conda activate ./envs✅ 2. 安装 PyTorch 和依赖 …...

Visual Studio已更新为17.14+集成deepseek实现高效编程

01 Visual Studio 2022 v17.14。 此更新侧重于全面提供出色的开发人员体验&#xff0c;侧重于稳定性和安全性以及 AI 改进。 02 GPT-4o代码完成模式 我们非常高兴地宣布&#xff0c;新的 GPT-4o Copilot 代码完成模型现已在 Visual Studio 17.14 中为 GitHub Copilot 用户…...

go 基础语法 【教程 go tour】

go 基础语法 【1】 教程go tour 1 包 变量 函数 变量不用声明 func swap(x, y string) (string, string) {return y, x }func main() {a, b : swap("hello", "world")fmt.Println(a, b) }也可以声明&#xff1a; 没有明确初始化的变量声明会被赋予对应…...

养生指南:五维打造健康新方式

一、饮食&#xff1a;天然搭配&#xff0c;科学进食 遵循 “食物多样化” 原则&#xff0c;早餐以红薯玉米粥搭配水煮蛋、凉拌黄瓜&#xff0c;开启活力一天&#xff1b;午餐选用糙米饭、番茄炖牛腩、蒜蓉空心菜&#xff0c;营养均衡&#xff1b;晚餐用冬瓜虾皮汤配上蒸芋头&a…...

网络爬虫学习之httpx的使用

开篇 本文整理自《Python3 网络爬虫实战》&#xff0c;主要是httpx的使用。 笔记整理 使用urllib库requests库的使用&#xff0c;已经可以爬取绝大多数网站的数据&#xff0c;但对于某些网站依然无能为力。 这是因为这些网站强制使用HTTP/2.0协议访问&#xff0c;这时urllib和r…...

无人机桥梁检测效率问题-高精度3D建模及航线规划

无人机桥梁检测效率问题-高精度3D建模及航线规划 无人机桥梁检测的效率分析 结论-并没有提升效率 飞行任务制定步骤繁琐且续航限制 需要首先对大桥建立高精度的3D建模&#xff0c;根据任务制定无人机的飞行路径以及动作&#xff0c;商用无人机续航通常仅30-40分钟&#xff0c…...

想免费使用 AWS 云服务器?注册、验证及开通全攻略

拥有一台 AWS 免费云服务器&#xff0c;可以轻松搭建个人网站、博客或部署 ChatGPT 等 AI 服务。本文详解如何 注册 AWS 账号、完成 信用卡验证&#xff0c;并在 AWS 控制台中 开通 EC2 实例&#xff0c;享受长达 12 个月的免费额度。 提示&#xff1a; 国内信用卡及银联借记卡…...

以太联 - Intellinet 闪耀台北 SecuTech 国际安全科技应用博览会

2025 年 5 月 7 日至 9 日&#xff0c;台北 SecuTech 国际安全科技应用博览会现场热闹非凡&#xff0c;以太联 - Intellinet 携旗下前沿产品与解决方案精彩亮相&#xff0c;成为展会上一道亮丽的风景线&#xff0c;吸引了众多业内人士的目光&#xff0c;收获了广泛关注与高度认…...

Pandas:数据分析中的缺失值检测、加载、设置、可视化与处理

本文目录&#xff1a; 一、检测数据集中的缺失值&#xff08;一&#xff09;缺失值的判断规则&#xff1a;&#xff08;二&#xff09;代码如下&#xff1a; 二、缺失值加载处理&缺失值设置&#xff08;一&#xff09;缺失值加载处理&#xff08;二&#xff09;缺失值设置 …...

【Linux系列】EVS 与 VBD 的对比

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

56 在standby待机打通uart调试的方法

修改点如下&#xff1a; 一&#xff0c;进入standby保证uart通 1, 去掉串口进入休眠RT_DEVICE_CTRL_SUSPEND:关闭uart&#xff0c;保证BSP_IO_Power_Down函数执行完前&#xff0c;串口都可以打印&#xff0c;和通过SifliUsartServer工具串口连接&#xff0c;并debug死机问题&…...

OceanBase 共享存储:云原生数据库的存储

目录 探会——第三届 OceanBase 开发者大会 重磅发布&#xff1a;OceanBase 4.3 开发者生态全面升级 实战演讲&#xff1a;用户案例与行业落地 OceanBase 共享存储架构解析 什么是共享存储架构&#xff1f; 云原生数据库的架构 性能、弹性与多云的统一 为何OceanBase能…...

安卓新建项目时,Gradle下载慢下载如何用国内的镜像

方法 1&#xff1a;修改 gradle-wrapper.properties 使用国内镜像 Gradle 的下载地址可以在 gradle-wrapper.properties 中修改&#xff0c;替换为国内镜像地址&#xff08;如阿里云、腾讯云等&#xff09;。 步骤 打开项目中的 gradle-wrapper.properties 文件&#xff08;路…...

讯联文库开发日志(五)登录拦截校验

零 在此之前&#xff0c;由于主播一直缺乏session&#xff0c;这次两个小时的寻找bug之旅也让我受益颇多 罪魁祸首&#xff1a;key值写错了&#xff0c;导致一直报错&#xff0c;不过这也让我了解了更多关于session的k-v结构 参数校验 我们需要在全局拦截器注解里面加两个方…...

PCB设计教程【入门篇】——电路分析基础-读懂原理图

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 目录 前言 一、原理图核心要素…...

C语言数据结构

单链表 头文件&#xff1a;lin.h #ifndef __LINK_H__ #define __LINK_H__ #include <stdio.h> #include <stdlib.h> typedef int DataType; /*节点数据类型*/ typedef struct node { DataType data; //数据域 struct node *pNext; …...

湖北理元理律师事务所债务优化方案:让还款与生活平衡成为可能

在现代社会&#xff0c;债务问题已经成为影响许多家庭生活质量的重要因素。如何在不影响基本生活的前提下合理规划还款&#xff0c;是众多债务人面临的实际难题。湖北理元理律师事务所推出的债务优化服务&#xff0c;正是针对这一需求而设计的专业解决方案。 该所的债务优化方…...

Java对象内存分配优化教学

用 “停车位” 的比喻理解这个问题 &#x1f697;&#x1f4a8; 假设你是一个停车场管理员&#xff08;JVM&#xff09;&#xff0c;现在有人&#xff08;程序员&#xff09;要停车&#xff08;new 对象&#xff09;。传统认知是&#xff1a; 堆内存 公共停车场 栈内存 临时…...

精度再升级,可到微米!单位自动换算平米和米

CAD图纸单位怎么看&#xff1f;精度怎么调&#xff1f; 长度测出来是什么单位&#xff1f; 面积一大串怎么回事&#xff1f; 坐标小数点位置不对怎么办&#xff1f; 点击直接获取CAD快速看图 首先说原理 CAD图纸在绘制时&#xff0c;一般情况下单位是&#xff1a; 长度---…...

【学习笔记】Sophus (Python) 使用文档

以下是一份针对 Sophus 库的 Python 使用文档&#xff0c;涵盖基础概念、安装方法、核心功能及代码示例。内容围绕 SO3&#xff08;3D旋转群&#xff09;和 SE3&#xff08;3D刚体变换群&#xff09;展开&#xff0c;适合机器人学、SLAM、三维几何等领域。 Sophus (Python) 使用…...

常见算法题目2 - 给定一个字符串,找出其中最长的不重复子串

算法题目2 - 给定一个字符串&#xff0c;找出其中最长的不重复子串 1. 问题描述 给定一个字符串&#xff0c;输出其最长的不重复子串&#xff0c;例如&#xff1a; String str "ababc"; 输出&#xff1a; abc以下根据两种搜索算法。 2. 算法解决 2.1 暴力循环法…...

如何配置jmeter做分布式压测

问&#xff1a;为何需要做分布式 答&#xff1a;当我们本地机器jmeter进行压测时&#xff0c;单台JMeter机器通常无法稳定生成2000 QPS&#xff08;受限于CPU、内存、网络带宽&#xff09;&#xff0c;本地端口耗尽&#xff1a;操作系统可用的临时端口&#xff08;Ephemeral P…...

Django 中的 ORM 基础语法

深入剖析 Django 中的 ORM 语法&#xff1a;从基础到实战进阶 在 Django 开发领域&#xff0c;ORM&#xff08;对象关系映射&#xff09;是开发者高效操作数据库的得力工具。它以简洁直观的 Python 代码&#xff0c;替代繁琐的 SQL 语句&#xff0c;极大提升了开发效率。本文将…...

C#对象初始化语句:优雅创建对象的黑科技

&#x1f4cc; 核心概念速览 对象初始化语句&#xff08;Object Initializer&#xff09;是C#中一种简洁高效的语法糖&#xff0c;允许在创建对象时直接初始化其公有字段或属性&#xff0c;无需依赖构造函数的重载。它的本质是对构造过程的扩展&#xff0c;尤其适合需要灵活设…...

【计算机网络】TCP如何保障传输可靠性_笔记

文章目录 一、传输可靠性的6方面保障二、分段机制三、超时重传机制四、流量控制五、拥塞控制 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 源网站 按TCP/IP 4层体系&#xff0c;TCP位于传输层&#xff0c;为应用层提供服务 一、传输可靠性的6方面保障…...

Robust Kernel Estimation with Outliers Handling for Image Deblurring论文阅读

Robust Kernel Estimation with Outliers Handling for Image Deblurring 1. 论文的研究目标与实际问题意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、模型与优势2.1 核心思路2.2 关键公式与技术细节2.2.1 非线性模糊模型与能量函数2.2.2 中间潜像更新与IRLS2.2.3…...

Android Studio 开发环境兼容性检索(AGP / Gradle / Kotlin / JDK)

本表检索了 Android 项目中常用构建工具的兼容性关系&#xff0c;包括&#xff1a; AGP&#xff08;Android Gradle Plugin&#xff09;Gradle&#xff08;构建工具&#xff09;KGP&#xff08;Kotlin Gradle Plugin&#xff09;JDK&#xff08;Java Development Kit&#xff…...

html主题切换小demo

主题切换功能为网页和应用程序提供了多样化的视觉风格与使用体验。实现多主题切换的技术方案丰富多样&#xff0c;其中 CSS 变量和 JavaScript 样式控制是较为常见的实现方式。 以下是一个简洁的多主题切换示例&#xff0c;愿它能为您的编程之旅增添一份趣味。 代码展示 <…...

AI架构职责分配——支持AI模块的职责边界设计

职责分配——支持AI模块的职责边界设计 在传统系统中&#xff0c;职责分配通常围绕“控制层处理逻辑、服务层执行业务、数据层持久化”进行划分。这种分工逻辑在纯业务系统中足以支撑高效协作与系统演进。然而&#xff0c;随着AI模块的引入&#xff0c;系统中新增了如模型推理…...