在 Vue 3 中使用外部配置文件实现动态表单校验规则
在使用 Vue 3 和 Element Plus 的项目中,表单校验是非常常见的需求。为了保持代码的清晰和可维护性,我们可以将 el-form
的校验规则提取到外部配置文件中进行管理。同时,我们还可以实现根据表单的其他字段,动态调整某些表单字段的校验规则。本文将介绍如何通过外部配置文件来动态实现表单校验逻辑。
场景描述
我们有一个活动表单,包含“活动标题”和“活动副标题”两个输入框:
- 活动标题:当活动副标题为空时,最大允许 32 个字符(其中中文字符算 2 个字符,英文算 1 个);当活动副标题不为空时,最大允许 16 个字符。
- 活动副标题:可选填,最大允许 26 个字符。
需求实现
为了实现这个需求,我们希望将校验逻辑写入到一个配置文件中,这样可以保持表单校验规则的统一和清晰。在 Element Plus 的 el-form
中,校验规则可以通过 validator
函数实现自定义验证,但需要动态获取表单模型的数据。
方案思路:
-
配置文件:将
rules
写在配置文件中,通过validator
函数来实现自定义验证。 -
传递
form
:在validator
函数中通过参数获取到form
数据,动态调整校验逻辑。
配置文件中的规则示例:
在配置文件中,我们可以定义校验规则并动态获取 form
模型的数据。
// validationRules.js
export const validationRules = (form) => ({
title: [
{
validator: (rule, value, callback) => {
const subtitle = form.subtitle;
const maxLength = subtitle ? 16 : 32;
const length = calculateLength(value);
if (length > maxLength) {
callback(new Error(`标题不能超过 ${maxLength} 个字符`));
} else {
callback();
}
},
trigger: 'blur',
},
],
});
// 计算字符长度函数
function calculateLength(value) {
let length = 0;
for (let char of value) {
if (/[一-龥]/.test(char)) {
length += 2; // 中文字符
} else {
length += 1; // 英文或其他字符
}
}
return length;
}
在组件中使用配置文件:
在 Vue 组件中,我们需要引入配置文件并通过传递表单模型数据来动态校验。
<template>
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
<el-form-item
label="活动标题"
prop="title"
:rules="rules.title"
:maxlength="form.subtitle ? 16 : 32"
>
<el-input v-model="form.title" placeholder="请输入活动标题" />
</el-form-item>
<el-form-item label="活动副标题" prop="subtitle">
<el-input
v-model="form.subtitle"
placeholder="请输入活动副标题"
maxlength="26"
@input="handleSubtitleChange"
/>
</el-form-item>
<el-button type="primary" @click="submitForm">提交</el-button>
</el-form>
</template>
<script setup>
import { ref } from 'vue';
import { validationRules } from './validationRules'; // 引入外部配置文件
import { ElMessage } from 'element-plus';
// 表单数据
const form = ref({
title: '',
subtitle: '',
});
// 表单引用
const formRef = ref(null);
// 动态校验规则,通过传入 form 数据
const rules = ref(validationRules(form.value));
// 当副标题变化时,重新触发标题的校验
const handleSubtitleChange = () => {
formRef.value.validateField('title');
};
// 提交表单
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
ElMessage.success('提交成功');
} else {
ElMessage.error('校验失败');
return false;
}
});
};
</script>
关键点:
-
配置文件动态校验:在配置文件中通过函数形式将
form
数据传递到rules
中,动态调整validator
函数中的逻辑。 -
在组件中引入:在组件中引入配置文件,并通过
ref
动态绑定表单模型,将模型传递给配置文件中的rules
。 - 保持配置统一:这样做的好处是,你可以将所有的校验规则提取到外部文件中,保持代码的统一性和可维护性。
通过这种方式,你可以避免在组件内编写过多的校验逻辑,同时实现动态校验,并且使代码更加整洁和复用。
image.png