You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vue3-mgt-template/src/views/demo/formItemWithRangeFields.vue

263 lines
8.1 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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这里newLoanRateMinnewLoanRateMax合并范围值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>