Vue3 + TypeScript + el-input 处理年份输入(最多只能输入四位数字,不能输入其他符号)
代码// 处理年份输入最多只能输入四位数字不能输入其他符号 const handleYearInput (value: string) { // 过滤掉所有非数字字符只保留数字 const numbersOnly value.replace(/[^\d]/g, ); // 限制4位 const limitedValue numbersOnly.slice(0, 4); // 转换为数字空字符串设为0 localCapitalInfo.capitalYear limitedValue ? 0 : parseInt(limitedValue, 10); }; el-input v-modellocalCapitalInfo.capitalYear clearable inputhandleYearInput /效果Vue3年份输入控制最佳实践vue3中 // 处理年份输入最多只能输入四位数字不能输入其他符号 const handleYearInput (value: string) { // 过滤掉所有非数字字符只保留数字 const numbersOnly value.replace(/[^\d]/g, ); // 限制4位 const limitedValue numbersOnly.slice(0, 4); // 转换为数字空字符串设为0 localCapitalInfo.capitalYear limitedValue ? 0 : parseInt(limitedValue, 10); }; ...... el-row :gutter10 el-col :span12 el-form-item label资金序号 label-positionright propcapitalNo el-input v-modellocalCapitalInfo.capitalNo clearable / /el-form-item /el-col el-col :span12 el-form-item label资金年份 label-positionright propcapitalYear el-input v-modellocalCapitalInfo.capitalYear clearable inputhandleYearInput / /el-form-item /el-col /el-row ...... el-row :gutter10 el-col :span24 el-form-item label资金年份 label-positionright el-input v-modelcapitalInfoStore.queryDTO.capitalYear clearable / /el-form-item /el-col /el-row 如何更好地实现这两处资金年份的输入控制在 Vue3 中可以通过以下几种方式更好地实现年份输入控制方案一使用计算属性 自定义指令推荐1. 创建自定义指令typescript// directives/inputDirectives.ts import { Directive } from vue // 只能输入数字的自定义指令 export const numberDirective: Directive { mounted(el) { el.addEventListener(input, (e: Event) { const input e.target as HTMLInputElement input.value input.value.replace(/[^\d]/g, ) }) } } // 限制最大长度的自定义指令 export const maxLengthDirective: Directive { mounted(el, binding) { const maxLength binding.value || 4 el.addEventListener(input, (e: Event) { const input e.target as HTMLInputElement if (input.value.length maxLength) { input.value input.value.slice(0, maxLength) } }) } }2. 在组件中使用vuetemplate el-row :gutter10 el-col :span12 el-form-item label资金年份 label-positionright propcapitalYear el-input v-model.numberlocalCapitalInfo.capitalYear :maxlength4 clearable v-number v-max-length4 blurvalidateYear / /el-form-item /el-col /el-row /template script setup langts import { ref, computed } from vue import { numberDirective, maxLengthDirective } from /directives/inputDirectives const vNumber numberDirective const vMaxLength maxLengthDirective // 使用计算属性处理年份 const localCapitalInfo ref({ capitalYear: 0 }) // 年份计算属性 const yearValue computed({ get() { return localCapitalInfo.value.capitalYear || }, set(value) { if (value ) { localCapitalInfo.value.capitalYear 0 } else { const num parseInt(value, 10) if (!isNaN(num) num 0) { localCapitalInfo.value.capitalYear Math.min(num, 9999) } } } }) // 验证年份 const validateYear () { const year localCapitalInfo.value.capitalYear if (year 1900 || year 2100) { // 可以添加错误提示 console.warn(请输入有效的年份1900-2100) } } /script方案二创建可复用的 Composable1. 创建 useYearInput Composabletypescript// composables/useYearInput.ts import { ref, computed, watch } from vue export function useYearInput(initialValue 0, options { min: 1900, max: 2100, maxLength: 4 }) { const rawValue refstring(initialValue?.toString() || ) const error refstring() // 处理输入 const handleInput (value: string) { // 只保留数字 const numbersOnly value.replace(/[^\d]/g, ) // 限制长度 rawValue.value numbersOnly.slice(0, options.maxLength) // 验证 validate() } // 验证年份 const validate () { if (rawValue.value ) { error.value return true } const yearNum parseInt(rawValue.value, 10) if (isNaN(yearNum)) { error.value 请输入有效的年份 return false } if (yearNum options.min || yearNum options.max) { error.value 年份范围${options.min}-${options.max} return false } error.value return true } // 获取数字值 const yearNumber computed(() { if (rawValue.value ) return 0 const num parseInt(rawValue.value, 10) return isNaN(num) ? 0 : num }) // 获取显示值 const displayValue computed({ get: () rawValue.value, set: (value: string) handleInput(value) }) return { rawValue, displayValue, yearNumber, error, handleInput, validate } }2. 在组件中使用vuetemplate el-row :gutter10 el-col :span12 el-form-item label资金年份 label-positionright propcapitalYear :erroryearInput.error el-input v-modelyearInput.displayValue :maxlength4 clearable placeholder请输入年份 bluryearInput.validate / /el-form-item /el-col /el-row /template script setup langts import { useYearInput } from /composables/useYearInput import { watch } from vue const yearInput useYearInput(2023, { min: 1900, max: 2100, maxLength: 4 }) // 如果需要可以监听数值变化 watch(() yearInput.yearNumber, (newVal) { // 更新到 store 或父组件 }) /script方案三创建 YearInput 组件最推荐1. 创建 YearInput 组件vue!-- components/YearInput.vue -- template el-input :model-valuedisplayValue :maxlength4 :placeholderplaceholder :clearableclearable :disableddisabled :error!!errorMessage inputhandleInput blurhandleBlur template #append v-ifshowSuffix年/template /el-input div v-iferrorMessage classerror-message {{ errorMessage }} /div /template script setup langts import { ref, computed, watch } from vue interface Props { modelValue?: number | string placeholder?: string clearable?: boolean disabled?: boolean showSuffix?: boolean minYear?: number maxYear?: number required?: boolean } const props withDefaults(definePropsProps(), { modelValue: 0, placeholder: 请输入年份, clearable: true, disabled: false, showSuffix: true, minYear: 1900, maxYear: 2100, required: false }) const emit defineEmits{ update:modelValue: [value: number] change: [value: number] validate: [isValid: boolean] }() const rawValue refstring() const errorMessage refstring() // 初始化 watch(() props.modelValue, (value) { if (value || value 0) { rawValue.value value.toString() } }, { immediate: true }) // 显示值 const displayValue computed(() rawValue.value) // 处理输入 const handleInput (value: string) { // 只保留数字 const numbersOnly value.replace(/[^\d]/g, ) // 限制长度 rawValue.value numbersOnly.slice(0, 4) // 实时更新 updateValue() } // 更新值 const updateValue () { if (rawValue.value ) { emit(update:modelValue, 0) emit(change, 0) return } const yearNum parseInt(rawValue.value, 10) if (!isNaN(yearNum)) { const finalValue Math.min(Math.max(yearNum, 0), 9999) emit(update:modelValue, finalValue) emit(change, finalValue) } } // 验证 const handleBlur () { validate() } const validate (): boolean { errorMessage.value if (props.required !rawValue.value) { errorMessage.value 年份不能为空 emit(validate, false) return false } if (!rawValue.value) { emit(validate, true) return true } const yearNum parseInt(rawValue.value, 10) if (isNaN(yearNum)) { errorMessage.value 请输入有效的年份 emit(validate, false) return false } if (yearNum props.minYear || yearNum props.maxYear) { errorMessage.value 年份范围${props.minYear}-${props.maxYear} emit(validate, false) return false } emit(validate, true) return true } // 暴露方法 defineExpose({ validate, clear: () { rawValue.value updateValue() } }) /script style scoped .error-message { color: #f56c6c; font-size: 12px; margin-top: 4px; } /style2. 在父组件中使用vuetemplate el-row :gutter10 el-col :span12 el-form-item label资金年份 label-positionright propcapitalYear YearInput v-modellocalCapitalInfo.capitalYear :min-year2000 :max-year2100 required / /el-form-item /el-col /el-row el-row :gutter10 el-col :span24 el-form-item label资金年份 label-positionright YearInput v-modelcapitalInfoStore.queryDTO.capitalYear :clearabletrue / /el-form-item /el-col /el-row /template script setup langts import YearInput from /components/YearInput.vue import { ref } from vue const localCapitalInfo ref({ capitalYear: 2023 }) // 使用 store import { useCapitalInfoStore } from /stores/capitalInfo const capitalInfoStore useCapitalInfoStore() /script方案四使用第三方库如 v-maskbashnpm install vue-the-maskvuetemplate el-input v-modelyearValue v-mask#### placeholderYYYY clearable / /template script setup langts import { ref, watch } from vue import { VueMaskDirective } from vue-the-mask const vMask VueMaskDirective const yearValue ref() /script总结建议推荐方案三创建YearInput组件封装性好可复用性强次推荐方案二使用 Composable逻辑复用方便简单场景可以使用计算属性 自定义指令优势统一处理逻辑避免重复代码支持验证和错误提示易于维护和扩展类型安全TypeScript根据项目复杂度和复用需求选择合适的方案组件化方式更适合长期维护的项目。

相关新闻

《QGIS快速入门与应用基础》138:元数据选项卡:图层描述信息

《QGIS快速入门与应用基础》138:元数据选项卡:图层描述信息

作者:翰墨之道,毕业于国际知名大学空间信息与计算机专业,获硕士学位,现任国内时空智能领域资深专家、CSDN知名技术博主。多年来深耕地理信息与时空智能核心技术研发,精通 QGIS、GrassGIS、OSG、OsgEarth、UE、Cesium、OpenLayers、Leaflet、MapBox 等主流工具与框架,兼具…

2026/7/3 15:26:23 阅读更多 →
二维码的多样应用是什么?

二维码的多样应用是什么?

视频二维码作为一种创新的信息传播工具,在数字时代展现出其独特的价值。它将视频内容与二维码结合,使得用户获取信息变得更加简单快捷。这种技术不仅提升了用户体验,还帮助品牌在竞争激烈的市场中脱颖而出。 便捷性:用户扫描二维…

2026/7/4 19:21:31 阅读更多 →
新手做外贸网站哪个平台更适合?(2026 避坑指南:先选“路线”,再选“工具”)

新手做外贸网站哪个平台更适合?(2026 避坑指南:先选“路线”,再选“工具”)

你第一次做外贸网站,最怕的不是“选贵了”,而是“建完才发现要重做”:结构要改、数据不通、多语言不同步、投放和SEO互相打架。 这篇避坑指南用一条最短决策链,帮你先确定路线,再选平台。 1)先给结论&am…

2026/7/3 15:26:27 阅读更多 →

最新新闻

百元头戴耳机内卷!vivo、REDMI新品全面对比

百元头戴耳机内卷!vivo、REDMI新品全面对比

当下头戴耳机新品层出不穷,vivo 与 REDMI 先后推出自家首款头戴降噪耳机,两款百元级新品定位相近却各有取舍。两种简约风格,配色各有特色从外观颜值上看,两款耳机均走极简圆润设计路线,无繁杂装饰,同时兼具…

2026/7/5 4:09:11 阅读更多 →
Pytest自动化测试进阶:工程化、数据驱动与性能优化实战

Pytest自动化测试进阶:工程化、数据驱动与性能优化实战

1. 项目概述:从“会用”到“精通”的自动化测试进阶如果你已经用pytest写过一些简单的测试用例,感觉它比unittest好用,断言更直观,夹具(fixture)也挺方便,那么恭喜你,你已经迈出了自…

2026/7/5 4:09:11 阅读更多 →
如何用JavaQuestPlayer三步搞定QSP游戏开发:终极Java游戏引擎指南

如何用JavaQuestPlayer三步搞定QSP游戏开发:终极Java游戏引擎指南

如何用JavaQuestPlayer三步搞定QSP游戏开发:终极Java游戏引擎指南 【免费下载链接】JavaQuestPlayer 项目地址: https://gitcode.com/gh_mirrors/ja/JavaQuestPlayer 还在为QSP游戏开发繁琐的编译测试流程而烦恼吗?JavaQuestPlayer为你带来革命性…

2026/7/5 4:07:11 阅读更多 →
奔驰音响升级:森索姆和柏林之声到底怎么选?

奔驰音响升级:森索姆和柏林之声到底怎么选?

一个是跟奔驰合作了17年的德国老牌,一个是兰博基尼御用的英国新贵。参数差这么多,实际听感差多少?施工有没有坑?拆开说。很多W214新款E级、W206 C级和W254 GLC车主提车后第一件事就是琢磨音响——原车那套7个喇叭的配置&#xff0…

2026/7/5 4:07:11 阅读更多 →
如何用FinalBurn Neo打造终极街机游戏库:完整指南与实战技巧

如何用FinalBurn Neo打造终极街机游戏库:完整指南与实战技巧

如何用FinalBurn Neo打造终极街机游戏库:完整指南与实战技巧 【免费下载链接】FBNeo FinalBurn Neo - We are Team FBNeo. 项目地址: https://gitcode.com/gh_mirrors/fb/FBNeo 你是否怀念街机厅的经典游戏体验?FinalBurn Neo(FBNeo&a…

2026/7/5 4:07:11 阅读更多 →
终极指南:用FanControl实现电脑风扇静音与散热的完美平衡

终极指南:用FanControl实现电脑风扇静音与散热的完美平衡

终极指南:用FanControl实现电脑风扇静音与散热的完美平衡 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending…

2026/7/5 4:05:10 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻