|
|
|
@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<div class="p-5 space-y-5 !bg-gray-100">
|
|
|
|
|
|
|
|
<el-card header="表单一个formItem中校验多个字段">
|
|
|
|
|
|
|
|
<el-form
|
|
|
|
|
|
|
|
:model="form"
|
|
|
|
|
|
|
|
label-width="120px"
|
|
|
|
|
|
|
|
:rules="rules"
|
|
|
|
|
|
|
|
ref="formRef"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
|
|
|
label="新贷款利率区间"
|
|
|
|
|
|
|
|
prop="newLoanRateRange"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.newLoanRateMin"
|
|
|
|
|
|
|
|
placeholder="最小值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('newLoanRateRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span style="width: 10%; text-align: center">至</span>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.newLoanRateMax"
|
|
|
|
|
|
|
|
placeholder="最大值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('newLoanRateRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
|
|
|
label="降息利率区间"
|
|
|
|
|
|
|
|
prop="newRateRange"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.newRateMin"
|
|
|
|
|
|
|
|
placeholder="最小值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('newRateRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span style="width: 10%; text-align: center">至</span>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.newRateMax"
|
|
|
|
|
|
|
|
placeholder="最大值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('newRateRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
|
|
|
label="放款金额区间"
|
|
|
|
|
|
|
|
prop="getAmtRange"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.getAmtMin"
|
|
|
|
|
|
|
|
placeholder="最小值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('getAmtRange')"
|
|
|
|
|
|
|
|
/><span style="width: 10%; text-align: center">至</span>
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.getAmtMax"
|
|
|
|
|
|
|
|
placeholder="最大值"
|
|
|
|
|
|
|
|
:maxlength="10"
|
|
|
|
|
|
|
|
@input="handleRateInput('getAmtRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
|
|
|
label="放款时间区间"
|
|
|
|
|
|
|
|
prop="getTimeRange"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<el-date-picker
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.getTimeMin"
|
|
|
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
placeholder="开始时间"
|
|
|
|
|
|
|
|
@change="handleRateInput('getTimeRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<span style="width: 10%; text-align: center">至</span>
|
|
|
|
|
|
|
|
<el-date-picker
|
|
|
|
|
|
|
|
style="width: 45%"
|
|
|
|
|
|
|
|
v-model="form.getTimeMax"
|
|
|
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
placeholder="结束时间"
|
|
|
|
|
|
|
|
@change="handleRateInput('getTimeRange')"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
|
|
@click="submitForm"
|
|
|
|
|
|
|
|
>点击校验表单</el-button
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
|
|
import { ref } from 'vue';
|
|
|
|
|
|
|
|
import { message } from '@/utils/message';
|
|
|
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
const formRef = ref(null);
|
|
|
|
|
|
|
|
const form = ref({
|
|
|
|
|
|
|
|
newLoanRateMin: '',
|
|
|
|
|
|
|
|
newLoanRateMax: '',
|
|
|
|
|
|
|
|
newRateMin: '',
|
|
|
|
|
|
|
|
newRateMax: '',
|
|
|
|
|
|
|
|
getAmtMin: '',
|
|
|
|
|
|
|
|
getAmtMax: '',
|
|
|
|
|
|
|
|
getTimeMin: '',
|
|
|
|
|
|
|
|
getTimeMax: '',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const validatorRange = (rule, value, callback) => {
|
|
|
|
|
|
|
|
const { minKey, maxKey, required } = rule.params || {};
|
|
|
|
|
|
|
|
const min = form.value[minKey];
|
|
|
|
|
|
|
|
const max = form.value[maxKey];
|
|
|
|
|
|
|
|
// 添加必填校验
|
|
|
|
|
|
|
|
if (required) {
|
|
|
|
|
|
|
|
// 如果两个字段都为空,则报错
|
|
|
|
|
|
|
|
if (!min && !max) {
|
|
|
|
|
|
|
|
return callback(new Error(rule.message || '请输入区间值'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 最小值有值,最大值为空
|
|
|
|
|
|
|
|
if (min && !max) {
|
|
|
|
|
|
|
|
return callback(new Error('请输入最大值'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 最大值有值,最小值为空
|
|
|
|
|
|
|
|
if (max && !min) {
|
|
|
|
|
|
|
|
return callback(new Error('请输入最小值'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 两者都有值,检查最大值是否小于最小值
|
|
|
|
|
|
|
|
if (min && max) {
|
|
|
|
|
|
|
|
const validNumberRegex = /^(0|[1-9]\d*)(\.\d+)?$/;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 校验最小值格式
|
|
|
|
|
|
|
|
if (!validNumberRegex.test(min)) {
|
|
|
|
|
|
|
|
return callback(new Error('最小值格式不正确'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 校验最大值格式
|
|
|
|
|
|
|
|
if (!validNumberRegex.test(max)) {
|
|
|
|
|
|
|
|
return callback(new Error('最大值格式不正确'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const minNum = parseFloat(min);
|
|
|
|
|
|
|
|
const maxNum = parseFloat(max);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isNaN(minNum) || isNaN(maxNum)) {
|
|
|
|
|
|
|
|
return callback(new Error('请输入有效的数字'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (maxNum < minNum) {
|
|
|
|
|
|
|
|
return callback(new Error('最大值不能小于最小值'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return callback();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const validatorDateRange = (rule, value, callback) => {
|
|
|
|
|
|
|
|
const { minKey, maxKey, required } = rule.params || {};
|
|
|
|
|
|
|
|
const min = form.value[minKey];
|
|
|
|
|
|
|
|
const max = form.value[maxKey];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加必填校验
|
|
|
|
|
|
|
|
if (required) {
|
|
|
|
|
|
|
|
if (!min && !max) {
|
|
|
|
|
|
|
|
return callback(new Error(rule.message || '请选择时间区间'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (min && !max) {
|
|
|
|
|
|
|
|
return callback(new Error('请选择结束时间'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (max && !min) {
|
|
|
|
|
|
|
|
return callback(new Error('请选择开始时间'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (min && max && dayjs(min).isAfter(dayjs(max))) {
|
|
|
|
|
|
|
|
return callback(new Error('开始时间不能晚于结束时间'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return callback();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const rules = ref({
|
|
|
|
|
|
|
|
// 重点1,这里newLoanRateMin,newLoanRateMax合并范围值newLoanRateRange,对应formItem的prop
|
|
|
|
|
|
|
|
newLoanRateRange: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 重点2,这里validatorRange是自定义的校验函数
|
|
|
|
|
|
|
|
validator: validatorRange,
|
|
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
|
|
// 重点3,这里params是传递给validatorRange的参数
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
minKey: 'newLoanRateMin',
|
|
|
|
|
|
|
|
maxKey: 'newLoanRateMax',
|
|
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
newRateRange: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
validator: validatorRange,
|
|
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
minKey: 'newRateMin',
|
|
|
|
|
|
|
|
maxKey: 'newRateMax',
|
|
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
getAmtRange: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
validator: validatorRange,
|
|
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
minKey: 'getAmtMin',
|
|
|
|
|
|
|
|
maxKey: 'getAmtMax',
|
|
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
getTimeRange: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
validator: validatorDateRange,
|
|
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
minKey: 'getTimeMin',
|
|
|
|
|
|
|
|
maxKey: 'getTimeMax',
|
|
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleRateInput = (field) => {
|
|
|
|
|
|
|
|
formRef.value.validateField(field, (valid) => {
|
|
|
|
|
|
|
|
console.log(`${field}校验结果:${valid}`);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const submitForm = () => {
|
|
|
|
|
|
|
|
formRef.value.validate((valid) => {
|
|
|
|
|
|
|
|
if (valid) {
|
|
|
|
|
|
|
|
message('校验成功', { type: 'success' });
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
message('校验失败', { type: 'warning' });
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped></style>
|