前言
以下内容都是基于element Plus 和 vue3
一个form-item校验两个下拉框
有时候不可避免会遇到需要一个form-item
校验两个下拉框的情况,比如:
这种情况下传统的校验已经无法实现,需要通过form
表单提供的自定义校验来实现。以上面的必填为例
<el-form-item label="工作时报" prop="workStartTime">
<el-select
v-model="states.formData.workStartTime"
filterable
style="width: 120px"
placeholder="请选择"
clearable
>
<el-option
v-for="item in states.workStartTimeList"
:key="item.completeTime"
:label="item.label"
:value="item.completeTime"
/>
</el-select>
<span style="padding: 0px 5px"> ~ </span>
<el-select
v-model="states.formData.workEndTime"
filterable
style="width: 120px"
placeholder="请选择"
clearable
ref="workEndTimeRef"
>
<el-option
v-for="item in states.workEndTimeList"
:key="item.completeTime"
:label="item.label"
:value="item.completeTime"
/>
</el-select>
</el-form-item>
const validatePass = (rule: any, value: any, callback: any) => {
let workEndTime = workEndTimeRef.value.selected.value
if (value && workEndTime) {
// 校验成功,这里也可以一些其他逻辑
callback()
} else {
callback(new Error('工作时报不能为空'))
}
}
const rules = reactive({
workStartTime: [
{
required: true,
validator: validatePass,
trigger: 'change',
},
],
})
注意点:
1、定义的校验方法要放在校验规则上面,不然会提示找不到方法
2、这点最重要,首先form-item
上绑定的属性是workStartTime
,所以你校验方法中只能拿到该属性对应的值。另一个下拉的值要先获取到,你必须在下拉上绑定一个ref
你可以通过打印这个ref
来找到另一个下拉的值。当第一个下拉改变后就会触发校验,这时只需要判断两个下拉是否都已经有值,如果没有值,返回提示信息就好。
下拉框加一个二次确认,确认值是否改变
以下图为例,当计划类型值的改变时需要清空其他值时,这时最好给与一个二次确认。确认是否改变,而不是直接改变,导致其他数据被清空,这样会很奇怪。
这里的问题是,当取消后应该显示原来显示的值。最初想的方向有点错了,想通过监听来实现,当取消时直接将旧值赋值给绑定的属性,但实际结果是监听一直被触发,确认弹窗无法被关闭。
其实实现起来挺简单,最怕的就是方向想错了。可以定义一个变量来保存旧值,然后将二次确认弹窗的部分加到下拉框change事件里
// 计划类型改变事件
const planTypeChange = val => {
if (states.lastPlanType) {
E_Msg.confirm('提示', '计划类型改变将清空所有资源对应的编码,是否确认修改?')
.then(() => {
emits('planTypeChange', val, true)
})
.catch(() => {
states.formData.planType = states.lastPlanType
})
} else {
states.lastPlanType = val
}
}
当第一次下拉选择时,不应该弹出二次确认,这时将当前选择的值记录,当下次下拉改变后,就会进行提示。
这里不用判断记录的值是否和当前选择的值相同,只有当下拉值改变后,才会触发change事件。change事件触发了,一定说明值改变了。
获取form校验的返回结果
有时候因为业务逻辑比较复杂,就会进行组件拆分。这时遇到的问题时,如何在父组件里获取到子组件校验后的返回值。查了一下确实可以实现
// 子组件
//获取表单数据
const getFormData = () => {
return baseFormRef.value.validate().then(res => {
console.log('校验结果:', res)
if (res) {
// 校验成功,将表单数据返回
return states.formData
} else {
// 检验失败,返回false,表示子组件表单检验不满足
return false
}
})
}
// 父组件,子组件的返回值是一个promise函数,这里要进行处理
// 这里比较特殊,父组件也需要进行校验,正常情况添加上 async和await就好
formRef.value.validate(async valid => {
if (valid) {
// 基本信息
const baseData = await baseRef.value.getFormData()
// 资源信息
const resourceData = resourceRef.value.getFormData()
console.log('保存的信息:', baseData, resourceData)
if (baseData && resourceData) {
}
}
})