input输入日期时间,自动格式化组件/工具

input输入日期时间,自动格式化组件/工具

组件/工具使用说明

  • 只能输入日期时间,不能选择
  • 日期时间格式 yyyy-MM-dd HH:mm:ss
  • 基于VUE框架
  • 输入效果见下图
    在这里插入图片描述

组件/工具解决的痛点

  • 组件库日期时间组件,选日期时间很花时间
    • 例如想快速得到 2021-12-14 20:10:22,需要先选日期,然后再选时间
  • 可以快速输入目标日期和时间,不用关注日期和时间分隔符 - : 空格

组件/工具需要实现的功能

  • 只允许输入数字
  • 限制输入日期范围
  • 按键删除时自动补入合法数字
  • 输入数字自动删除后一位数字
  • 输入和删除时光标位置移动
  • 检测复制粘贴到输入框的内容
  • 输入完成时,按回车键自动失焦
  • 处理输入的不符合规则的日期

功能代码实现

  • HTML
<input v-model="inOutTime"@focus="onFocus"@blur="onBlur"@input="inputDateTime($event)"@keydown="onKeydown"ref="inputDate"class="inputDate":class="[`xxxx-${size}`]" />
<style scoped>
.inputDate {width: 100%;height: 40px;line-height: 40px;padding-left: 10px;border: none;outline: none;border-radius: 4px;border: 1px solid #dcdfe6;
}
.inputDate:focus {border-color: #409eff;
}
.xxxx-default {height: 40px;line-height: 40px;
}
.xxxx-medium {height: 36px;line-height: 36px;
}
.xxxx-small {height: 32px;line-height: 32px;
}
.xxxx-mini {height: 28px;line-height: 28px;
}
</style>
  • 实时获取输入框值和光标位置
    function inputDateTime(ev) {// 输入框光标起始位置let selectionStart = this.$refs.inputDate.selectionStart;let selectionEnd = this.$refs.inputDate.selectionEnd;// 输入框的valueconsole.log(ev.target.value);}
  • 处理输入框的值和光标位置的功能函数
// 格式化日期对象
function dateToStr(datetime) {if (!datetime) {return '';}let year = datetime.getFullYear();let month = datetime.getMonth() + 1;let date = datetime.getDate();let hour = datetime.getHours();let minutes = datetime.getMinutes();let second = datetime.getSeconds();if (month < 10) {month = "0" + month;}if (date < 10) {date = "0" + date;}if (hour < 10) {hour = "0" + hour;}if (minutes < 10) {minutes = "0" + minutes;}if (second < 10) {second = "0" + second;}let time = year + "-" + month + "-" + date + " " + hour + ":" + minutes + ":" + second;return time;
}
// 定义分割符位置对象
const del = {4: '-',7: '-',10: ' ',13: ':',16: ':'
}
/*** @param {*} str 日期字符串 2021-02-23 22:00:00* @param {*} selectionStart 输入光标起始位置 从1开始*/
export function formatStringDate(str, selectionStart) {// 粘贴时间校验if (!/^[0-9-:\s]{18,20}$/.test(str) || str.length < 18) {return {newDate: dateToStr(new Date()), startB: 19};}// 校验纯数字是否小于13位let numStr = str.replace(/-|:|s|\s/g, '');if (numStr.length < 13) {return {newDate: dateToStr(new Date()), startB: 19};}// 校验当前输入的是不是数字const num = /^[0-9]$/;// 字符查询从0开始let startB = selectionStart;selectionStart = selectionStart - 1;let arrDate = str.split('');// 按键删除if (arrDate.length < 19) {if (del[startB]) {// 删除的是分隔符arrDate.splice(startB, 0, del[startB])} else {// 如果删除的是数字,补位1// 第一位补2 第二位补0let obj = {0: '2',1: '0',5: '0'}arrDate.splice(startB, 0, obj[startB] || '1')}str = arrDate.join('');} else {// 按键输入// 拿到输入的字符const str2 = str.slice(selectionStart, selectionStart + 1);if (!num.test(str2)) {// 删除非法字符arrDate.splice(selectionStart, 1);return {newDate: arrDate.join(''), startB};}// 输入的是数字,删除当前位置下一位数字,遇到- : 空格,往后移动一位const str3 = str.slice(selectionStart + 1, selectionStart + 2);const reg1 = /^(-|:|s|\s)$/;if (reg1.test(str3)) {// 下一位非数字,往后移动一位进行删除arrDate.splice(selectionStart + 2, 1);// 光标往后移动一位startB++;}// 下一位是数字if (num.test(str3)) {arrDate.splice(selectionStart + 1, 1);}}// 去除分隔符('2022-02-23 20:20:20')及空格let str1 = arrDate.join('').replace(/-|:|s|\s/g, '');// 年月日校验 2000 ~ 2099const regDate = /^20([0-9][0-9])-(0[1-9]|1[0-2])-([0-2][0-9]|3[01])$/;const regTime = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]/;// 年月日let ymd = '';if (str1.length >= 8) {ymd = (str1).match(/(\d{4})(\d{2})(\d{2})/).filter((item, index) => index > 0).join('-');}if (!regDate.test(ymd)) {// 删除非法字符,返回原值const reArr = str.split('');reArr.splice(selectionStart, 1);return {newDate: reArr.join(''), startB};}// 时分秒let hmsStr = (str1).slice(8), hms;if (hmsStr.length >= 6) {hms = hmsStr.match(/(\d{2})(\d{2})(\d{2})/).filter((item, index) => index > 0).join(':');}if (!regTime.test(hms)) {// 删除非法字符,返回原值const reArr = str.split('');reArr.splice(selectionStart, 1);return {newDate: reArr.join(''), startB};}return {newDate: `${ymd} ${hms}`, startB};
}
  • 日期时间合法校验
function strDateTime(str) {var reg = /^(\d{4})(-|\/)(\d{2})\2(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;var r = str.match(reg);if (r == null) return false;var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);return (d.getFullYear() === Number(r[1]) && (d.getMonth() + 1) === Number(r[3]) && d.getDate() === Number(r[4]) && d.getHours() === Number(r[5]) && d.getMinutes() === Number(r[6]) && d.getSeconds() === Number(r[7]));
}
  • 设置光标位置
// 两个参数必传
this.$refs.inputDate.setSelectionRange(selectionStart, selectionStart);
  • 完整代码
<template><div><input v-model="inOutTime"@focus="onFocus"@blur="onBlur"@input="inputDateTime($event)"@keydown="onKeydown"ref="inputDate"class="inputDate":class="[`xxxx-${size}`]" /></div>
</template>
<script>
import { formatStringDate } from "utils";
import { dateToStr } from "public";
export default {props: {initTime: {type: String,required: true,default: dateToStr(new Date())},size: {type: String,default: 'small'}},data() {return {inOutTime: this.initTime}},methods: {inputDateTime(ev) {let selectionStart = this.$refs.inputDate.selectionStart;const options = formatStringDate(ev.target.value, selectionStart);this.inOutTime = options.newDate;if (options.startB !== selectionStart) {selectionStart = options.startB;}this.$nextTick(() => {this.$refs.inputDate.setSelectionRange(selectionStart, selectionStart);})},onFocus() {},onBlur() {if (!this.strDateTime(this.inOutTime)) {this.inOutTime = dateToStr(new Date());}},onKeydown(e) {let keyCode = window.event ? e.keyCode : e.which;// 回车键->输入框失焦if (keyCode === 13) {this.$refs.inputDate.blur();if (!this.strDateTime(this.inOutTime)) {this.inOutTime = dateToStr(new Date());}this.$emit('getTime', this.inOutTime);}},strDateTime(str) {var reg = /^(\d{4})(-|\/)(\d{2})\2(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;var r = str.match(reg);if (r == null) return false;var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);return (d.getFullYear() === Number(r[1]) && (d.getMonth() + 1) === Number(r[3]) && d.getDate() === Number(r[4]) && d.getHours() === Number(r[5]) && d.getMinutes() === Number(r[6]) && d.getSeconds() === Number(r[7]));}}
}
</script>

补充说明

  • 若需要实时获取处理之后的日期时间,可以在组件上使用v-model,具体代码请参考vue文档
  • 组件基于VUE编写,核心方法formatStringDate不依赖框架,原生JS、react均可使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang关于成员变量使用:=

错误 错误原因 结构体成员变量不能与:一起用&#xff0c;这是一个语法错误。

C#(五十八)之C#List

前几天&#xff0c;看同事写的代码中有list相关的字眼&#xff0c;百度了一下&#xff0c;原来是C#中list泛型集合。 了解一下。 List&#xff1a;泛型集合&#xff0c;List<T>类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现 IList<T> 泛型…

arcgis拓扑检查

不能有悬挂点 不能有伪结点***路网处理很重要&#xff0c;看研究吧。 一直默认到最后。 导入要素类&#xff0c;单个 toupu2右键新建拓扑&#xff08;T&#xff09; 一般选不能有悬挂点&#xff0c;不能重叠。 一路默认 是 拉进图层可视化 线要素的话记得添加字段length&#…

OSPF和VLAN综合实验

目录 题目 1.IP地址的规划设计 2.搭建拓扑并进行基础IP配置 3.配置虚拟局域网 1&#xff09;按子网划分要求配置PC1和PC2 检测&#xff1a;输入[SW1]display vlan进行检查 配置路由器R3 检测&#xff1a;用PC1去访问PC2 2&#xff09;配置拓扑中其余路由器的网关以及回…

使用RabbitMQ

使用RabbitMQ 1 Docker安装RabbitMQ 1.1 安装RabbitMQ # 下载含有管理页面的镜像 docker pull rabbitmq:3.8.8-management# 创建容器 # 5672&#xff1a;应用访问端口&#xff1b;15672&#xff1a;控制台Web端口号&#xff1b; docker run -itd \ --namemy-rabbitmq \ --re…

OpenCV 优化和改进图像处理应用功能的方法与实践

OpenCV 优化和改进图像处理应用功能的方法与实践 导语一、性能优化二、算法改进三、用户体验改进四、应用实践示例&#xff1a;实时图像滤波总结 导语 图像处理应用是计算机视觉和图像处理领域的关键应用之一&#xff0c;通过对图像进行处理和分析&#xff0c;可以提取有用的信…

创建一门简单的解释性编程语言并实现它的解释器

背景 最近刷到大佬的教程&#xff0c;跟着学一下 效果 开始时 输入姓名和年龄后 代码 自创编程语言SimpleScript: 自创一门简易脚本支持中文编程 (gitee.com) 解析 1.词法分析 将程序的每个字符串精准划分出来&#xff0c;形成多个单词Token 2.语法分析 将各段Token再…

Android 查看ANR和Crash日志(adb bugreport)

今天测试那儿出了个ANR&#xff0c;我自己手机没问题&#xff0c;很烦&#xff0c;定位不了位置。 于是还是得用ADB连接来看一下&#xff0c;之前用&#xff0c;但是老是会忘记&#xff0c;今天总结一下。 ADB命令查看应用包名_adb查看包名命令_&岁月不待人&的博客-C…

TeeChart for.NET Crack

TeeChart for.NET Crack TeeChart for.NET为各种图表需求提供了图表控件&#xff0c;包括金融、科学和统计等重要的垂直领域。它可以处理您的数据&#xff0c;在各种平台上无缝创建信息丰富、引人入胜的图表&#xff0c;包括Windows窗体、WPF、带有HTML5/Javascript渲染的ASP.N…

【C++】string类模拟

文章目录 成员变量和查看接口迭代器&#xff08;读和读写&#xff09;operator[]&#xff08;读和读写&#xff09;c_str()size() 构造函数用字符串构造用对象构造&#xff08;两种方法&#xff09;析构 赋值运算符重载扩容和调整reserve()resize()clear() 增删查改push_back()…

产业大模型刚开卷,京东跑进“最后半公里”

点击关注 文&#xff5c;姚 悦 编&#xff5c;王一粟 “京东一直在探索哪些产品、技术、场景可以真正把大模型用起来&#xff0c;在我们内部的场景中反复验证后&#xff0c;才决定在7月份对外发布&#xff0c;现在我们在零售、健康、物流、金融等业务场景里已经积累了一些经…

记一次阿里云被挖矿处理记录

摘要 莫名其妙的服务器就被攻击了&#xff0c;又被薅了羊毛&#xff0c;当做免费的挖矿劳动力了。 一、起因 上班&#xff08;摸鱼&#xff09;好好的&#xff0c;突然收到一条阿里云的推送短信&#xff0c;不看不知道&#xff0c;两台服务器被拉去作为苦力&#xff0c;挖矿去…

迭代读取文件

使用 torch.utils.data.dataset.Dataset 收集数据信息&#xff0c;创建数据集。 使用 import torch.utils.data.dataloader 创建一个可以批量迭代的数据载入器&#xff0c;并通过 for 循环批量读取所有文件的数据。 import torch.utils.data.dataset as dataset import torch…

光伏并网逆变器低电压穿越MATLAB仿真模型

使用MATLAB 2017b搭建 光伏逆变器低电压穿越仿真模型&#xff0c;boost加NPC拓扑结构&#xff0c;基于MATLAB/Simulink建模仿真。具备中点平衡SVPWM控制&#xff0c;正负序分离控制&#xff0c;pll&#xff0c;可进行低电压穿越仿真。 控制结构完整&#xff0c;波形完美&…

java学习路程之篇二、知识点、配置JAVA_HOME、跨平台、JVM、JRE、JDK

文章目录 1、Java背景介绍2、Java跨平台性3、JDK的下载和安装4、第一个Java程序5、HelloWorld案例详解6、JVM、JRE和JDK7、配置JAVA_HOME 1、Java背景介绍 2、Java跨平台性 3、JDK的下载和安装 4、第一个Java程序 5、HelloWorld案例详解 6、JVM、JRE和JDK 7、配置JAVA_HOME

MySQL(2)

建表 mysql> create table work(-> ‘部门号’ int(11) not null,-> ‘职工号’ int(11) not null,-> ‘工作时间’ date not null,-> ‘工资’ float(8,2) not null,-> ‘政治面貌’ varchar(10) not null default 群众,-> ‘姓名’ varchar(20) not nu…

ELK 企业级日志分析系统

目录 一&#xff1a;ELK 介绍 1、ELK 简介 2、filebeat 结合 logstash 好处 3、为什么要使用 ELK 4、完整日志系统基本特征 5、ELK 的工作原理 二&#xff1a;ELK Elasticsearch 集群部署 1、环境准备 2、部署 Elasticsearch 软件 &#xff08;1&#xff09;安装elasti…

在线考试系统

在线考试系统 简介 该系统由C#开发语言开发&#xff0c;数据库是sql server2016&#xff0c;前端用到的前端技术有Bootstrap&#xff0c;js&#xff0c;css等前端技术&#xff0c;同时用到的.Net Core MVC的技术框架。另外本系统也支持mysql&#xff0c;暂未调试。 该系统是…

计算机存储设备

缓存为啥比内存快 内存使用 DRAM 来存储数据的、也就是动态随机存储器。内部使用 MOS 和一个电容来存储。 需要不停地给它刷新、保持它的状态、要是不刷新、数据就丢掉了、所以叫动态 、DRAM 缓存使用 SRAM 来存储数据、使用多个晶体管(比如6个)就是为了存储1比特 内存编码…

Element-UI el-table属性row-class-name用法

文章目录 前言官方示例自定义条件样式设置背景颜色样式stripe属性 设置背景颜色样式设置字体颜色总结 前言 可以通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class&#xff0c;表明该行处于某种状态。 官方示例 代码如下&#xff1a; <el-table…