查看: 255|回复: 3

Element Plus表单组件验证与日期时间选择器实战

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
Element Plus 2.x 配合 Vue 3.2+ 和 TypeScript 4.5+ 时,表单类组件的核心是数据绑定、规则验证和值格式控制。下面按 Form、DatePicker、DateTimePicker、TimePicker、TimeSelect、ColorPicker 的使用路径重组原文代码与 API,并给出容易出错的排查点。

一、Form:用 ref 获取实例,用 rules 管理验证
通过 ref<FormInstance>() 获取表单实例,reactive 创建 model,FormRules 定义规则。required、min、max、type、trigger 分别控制必填、长度、邮箱格式和触发时机。提交时调用 formRef.value.validate 回调,valid 为 true 才提交;重置调用 resetFields。
  1. <script setup lang='ts'>
  2. import { ref, reactive } from 'vue'
  3. import type { FormInstance, FormRules } from 'element-plus'
  4. const formRef = ref<FormInstance>()
  5. const form = reactive({ username: '', password: '', email: '' })
  6. const rules = reactive<FormRules>({
  7.   username: [
  8.     { required: true, message: '请输入用户名', trigger: 'blur' },
  9.     { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
  10.   ],
  11.   password: [
  12.     { required: true, message: '请输入密码', trigger: 'blur' },
  13.     { min: 6, message: '密码至少 6 位', trigger: 'blur' }
  14.   ],
  15.   email: [
  16.     { required: true, message: '请输入邮箱', trigger: 'blur' },
  17.     { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
  18.   ]
  19. })
  20. const handleSubmit = async () => {
  21.   if (!formRef.value) return
  22.   await formRef.value.validate((valid) => {
  23.     if (valid) console.log('提交成功', form)
  24.     else console.log('验证失败')
  25.   })
  26. }
  27. const handleReset = () => { formRef.value?.resetFields() }
  28. </script>
  29. <template>
  30.   <el-form ref='formRef' :model='form' :rules='rules' label-width='80px'>
  31.     <el-form-item label='用户名' prop='username'>
  32.       <el-input v-model='form.username' placeholder='请输入用户名' />
  33.     </el-form-item>
  34.   </el-form>
  35. </template>
复制代码

自定义验证器用于确认密码等跨字段校验:validator 接收 rule、value、callback,比较 value 与 form.password,不一致时 callback(new Error('两次输入密码不一致')),一致时 callback()。注意必须调用 callback 返回结果。
  1. const validateConfirmPassword = (rule: any, value: any, callback: any) => {
  2.   if (value !== form.password) callback(new Error('两次输入密码不一致'))
  3.   else callback()
  4. }
  5. const rules = reactive<FormRules>({
  6.   confirmPassword: [
  7.     { required: true, message: '请再次输入密码', trigger: 'blur' },
  8.     { validator: validateConfirmPassword, trigger: 'blur' }
  9.   ]
  10. })
复制代码

动态表单用 domains 数组保存行数据,addDomain 通过 Date.now() 生成 key 并 push,removeDomain 用 splice 删除。原文提醒:动态表单的 prop 需要使用数组索引,例如 prop='domains.0.value'。行内查询表单直接设置 :inline='true',配合 el-form-item 和 el-select 使用。
  1. const addDomain = () => { form.domains.push({ key: Date.now(), value: '' }) }
  2. const removeDomain = (index: number) => { form.domains.splice(index, 1) }
复制代码

Form 排查点:prop 必须与 model 字段名一致;自定义验证器必须调用 callback;resetFields 会重置为初始值并清除验证状态;el-form 还提供 validateField、clearValidate、scrollToField 等方法。

二、DatePicker:范围、禁用日期与快捷选项
DatePicker 的 type 可取 year、month、date、dates、week、daterange、monthrange 等。日期范围选择时 v-model 为数组,format 控制显示格式,value-format 控制绑定值格式,原文推荐使用 YYYY-MM-DD。
  1. <el-date-picker v-model='dateRange' type='daterange' start-placeholder='开始日期' end-placeholder='结束日期' format='YYYY-MM-DD' value-format='YYYY-MM-DD' />
复制代码

限制可选日期通过 disabled-date 函数完成,返回 true 表示禁用。下面示例禁用今天之前的日期,以及只允许选择工作日。
  1. const disabledDate = (time: Date) => time.getTime() < Date.now() - 8.64e7
  2. const disabledWeekends = (time: Date) => {
  3.   const day = time.getDay()
  4.   return day === 0 || day === 6
  5. }
复制代码

快捷选项使用 shortcuts 数组,value 可以是返回 Date 数组的函数。原文给出的最近一周、最近一个月、最近三个月分别按 3600 * 1000 * 24 * 7、30、90 计算。
  1. const shortcuts = [
  2.   { text: '最近一周', value: () => { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); return [start, end] } },
  3.   { text: '最近一个月', value: () => { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); return [start, end] } },
  4.   { text: '最近三个月', value: () => { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); return [start, end] } }
  5. ]
复制代码

三、DateTimePicker:精确到时分秒
需要选择日期时间时使用 type='datetime',日期时间范围使用 type='datetimerange'。default-time 可设置选中日期后的默认时间,例如 new Date(2024, 0, 1, 9, 0, 0) 对应 2024-01-01 09:00:00。时间格式中 HH 为 24 小时制,hh 为 12 小时制。
  1. <el-date-picker v-model='dateTime' type='datetime' format='YYYY-MM-DD HH:mm:ss' value-format='YYYY-MM-DD HH:mm:ss' :default-time='defaultTime' />
复制代码

四、TimePicker:固定间隔与时间范围
TimePicker 通过 format、value-format 控制时间格式,is-range 开启时间范围选择。disabled-hours、disabled-minutes、disabled-seconds 接收函数,返回需要禁用的小时、分钟、秒数组。
  1. <el-time-picker v-model='timeRange' is-range start-placeholder='开始时间' end-placeholder='结束时间' />
  2. const disabledHours = () => [...Array(9).keys(), ...Array(6).keys().map(i => i + 18)]
  3. const disabledMinutes = (hour: number) => (hour === 9 || hour === 17) ? [0, 1, 2, 3, 4, 5] : []
复制代码

五、TimeSelect:固定时间列表
TimeSelect 适合预约、排班等固定时间列表场景。start、end 控制起止时间,step 控制间隔,时间格式为 HH:mm,例如 step='00:30' 表示 30 分钟一档。
  1. <el-time-select v-model='time' start='09:00' end='18:00' step='00:30' placeholder='选择时间' />
复制代码

六、ColorPicker:透明度与预设颜色
ColorPicker 支持 hex、rgb、hsv 等颜色格式。show-alpha 开启透明度选择,predefine 传入预设颜色数组。
  1. <el-color-picker v-model='color' show-alpha :predefine='predefineColors' />
  2. const predefineColors = ['#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585']
复制代码

七、实践中的排查顺序
先检查 el-form 的 model、rules 是否绑定正确,再检查 el-form-item 的 prop 是否与字段路径一致;跨字段验证要确认 callback 被调用;日期范围要确认 v-model 是数组;需要字符串提交时统一设置 value-format;禁用日期函数返回布尔值;时间禁用函数返回数组;TimeSelect 的 step 不要写成非法时间格式;ColorPicker 预设颜色使用数组传入。按这个顺序排查,大部分表单组件的绑定与格式问题都能快速定位。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Element Plus表单组件验证与日期时间选择器实战

楼主这篇整理得挺系统的,按 Form 到各种选择器的路径来拆,排查点也标得很清楚,对刚上手 Element Plus 2.x 的人很友好。我补充几个自己踩过的坑,供参考。 Form 这块,validate 其实返回的是 Promise,除了回调写法,也可以用 try/catch 配 await,失败时能直接拿到各字段的错误对象,方便定位是哪个 prop 没过。另外 resetFields 依赖 el-form-item 的 prop 和 model 的初始值,如果字段初始值是空字符串而你想重置成某个默认值,得在 onMounted 里先赋一次初值,否则重置回来还是空。 自定义验证器那里,跨字段校验除了 confirmPassword,改密码时最好也触发一次确认密码的校验,否则用户先填确认密码再改密码,确认框的状态不会自动刷新,可以用 validateField 手动补一刀。 动态表单的 prop 用数组索引这点很关键,另外删除行之后索引会整体前移,如果每行还有独立的校验状态,建议 key 一定要稳定,不要用 index 当 key,否则删中间行容易出现验证状态错位。 日期时间选择器方面,format 只管显示,value-format 才决定绑定值的类型,两个都不写的话拿到的是 Date 对象,直接传给后端容易被序列化成 ISO 字符串。日期范围选择器初始化时如果给了空数组或者 n
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Element Plus表单组件验证与日期时间选择器实战

整理得挺系统的,Form 这条线把 ref 拿实例、reactive 建 model、FormRules 管规则串得很清楚。几个排查点都踩在痛点上,尤其是自定义验证器必须调用 callback 这一条,实际项目里漏掉之后表单会一直卡在校验状态,很难一眼看出来。动态表单 prop 要用数组索引拼这个细节也很实用,很多人写成固定字段名,结果验证完全不生效。resetFields 的行为也值得强调,它是回到初始值而不是清空,如果 model 初始化时带了默认值,重置后要注意这个差异。 另外有个小地方可以留意:validate 本身既支持 Promise 也支持回调,示例里 await 加回调两种方式叠在一起,实际写的时候选一种会更清晰,比如直接 try/catch 包 await,或者纯回调处理。 DatePicker 那段到 value-format 好像被截断了,后面的 DateTimePicker、TimePicker、TimeSelect、ColorPicker 还没看到,挺期待补全的,特别是 format 和 value-format 混用、以及时间类组件绑定值类型不一致时的排查思路,这些在实际联调后端接口时最容易出问题。
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Element Plus表单组件验证与日期时间选择器实战

表单这部分整理得挺清楚的,尤其是自定义验证器必须调用 callback 这一点,确实是新手最容易漏的地方,不写 callback 就会出现“一直在验证中”或者规则不生效的假象。动态表单用数组索引拼 prop 的提醒也很实用,prop 和 model 字段对不上时,校验不触发又不报错,排查起来很费劲。 另外看到提交那段用了 await 加回调的写法,顺带提一句:validate 传回调时返回的是 Promise,不传回调且校验失败会走 reject,实际项目里最好统一一种写法,或者加上 try/catch,不然控制台容易冒未捕获的异常。resetFields 重置为初始值并清验证状态这点也值得强调,很多人以为它只是清空输入。 日期选择器这边 format 和 value-format 分开控制展示值和绑定值,这个区分很关键,daterange 的 v-model 必须是数组,清空后要注意拿到的是 null 而不是空数组,后面做查询参数处理时容易踩坑。不过帖子好像到 value-format 这里就断了,禁用日期和快捷选项还没展开,期待楼主补完 DateTimePicker、TimePicker 那几块,特别是时间范围校验和默认值处理的经验。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-31 07:52 , Processed in 0.026575 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部