喵~
今天分享一篇在 ElementPlus 中使用 el-form 動態(tài)切換校驗規(guī)則 的實(shí)用方法。
一、問題概述
作為前端開發(fā)人員,在開發(fā)項目中,特別是后臺管理系統(tǒng),表單的使用是必不可少的。當(dāng)業(yè)務(wù)需求復(fù)雜時,常常需要根據(jù)不同的參數(shù)動態(tài)切換校驗規(guī)則。
當(dāng)動態(tài)切換校驗規(guī)則時,可能會出現(xiàn)一些意想不到的狀況,
比如:
問題 1
- 如果觸發(fā)了一個規(guī)則,表單報紅后沒有reset,再切換新規(guī)則,則原有規(guī)則的報紅依舊顯示的問題;
問題 2
- 表單會主動觸發(fā)新規(guī)則的校驗,導(dǎo)致表單直接報紅;
根據(jù)上述2個問題,解決方案如下:
二、項目配置
| 名稱 | 版本 |
|---|---|
| element-plus | ^2.8.8 |
| vue | ^3.5.12 |
| typescript | ~5.6.3 |
這里采用了 vue + ts 的開發(fā)方式,不喜歡 ts 的小伙伴可以根據(jù)項目自行刪除不需要的代碼~
三、解決方案
整體代碼是在 ElementPlus form 校驗功能模塊的基礎(chǔ)上進(jìn)行優(yōu)化升級的~
代碼做了精簡,重點(diǎn)突出解決方案的代碼~
源碼在此處:https://element-plus.org/zh-CN/component/form.html

微信截圖_20241124141629.png
項目引入必要代碼
import { reactive, ref } from 'vue'
import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
接下來進(jìn)行優(yōu)化升級:
1. 定義規(guī)則
(1)TS接口
interface IRuleFormOne {
name: string
region: string
count: string
}
interface IRuleFormTwo {
delivery: boolean
location: string
type: string[]
resource: string
desc: string
}
/**
* 此處需要匯總一個完整規(guī)則,用于整體表單
*/
interface RuleForm extends IRuleFormOne, IRuleFormTwo{}
(2)規(guī)則
const rulesOne = reactive<FormRules<IRuleFormOne>>({
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
],
region: [
{
required: true,
message: 'Please select Activity zone',
trigger: 'change',
},
],
count: [
{
required: true,
message: 'Please select Activity count',
trigger: 'change',
},
],
})
const rulesTwo = reactive<FormRules<IRuleFormTwo>>({
location: [
{
required: true,
message: 'Please select a location',
trigger: 'change',
},
],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change',
},
],
resource: [
{
required: true,
message: 'Please select activity resource',
trigger: 'change',
},
],
desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
})
/**
* 可以先給表單賦一個初始規(guī)則
*/
const rules = ref<FormRules>(rulesOne)
2. 表單值
const ruleForm = reactive<RuleForm>({
name: 'Hello',
region: '',
count: '',
delivery: false,
location: '',
type: [],
resource: '',
desc: '',
})
3. 功能按鈕
這里不是重點(diǎn),用什么切換都可以,此處我用了兩個普通按鈕,并定義了 handleClickRule 方法來切換規(guī)則
/**
* Template部分
*/
<el-button-group class="rule-btn-group">
<el-button :type="actBtn === 1 ? 'primary' : ''" @click="handleClickRule(1)">規(guī)則一</el-button>
<el-button :type="actBtn === 2 ? 'primary' : ''" @click="handleClickRule(2)">規(guī)則二</el-button>
</el-button-group>
/**
* TS部分
*/
const actBtn = ref(1)
4. 實(shí)現(xiàn)切換規(guī)則
解決問題1
/**
* 這里是 Element Plus 原有代碼,不需要優(yōu)化,只是后面會用到,所以直接展示在這里
*/
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
/**
* 重點(diǎn)在這里!
*/
function handleClickRule(idx: number) {
actBtn.value = idx
switch (idx) {
case 1:
/**
* 這一行很關(guān)鍵,解決問題1,切換前,先清除已有的報紅
*/
resetForm(ruleFormRef.value)
rules.value = rulesOne
break
case 2:
resetForm(ruleFormRef.value)
rules.value = rulesTwo
break
default:
break
}
}
解決問題2
el-form 添加一條屬性配置即可解決:
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
:rules="rules"
label-width="auto"
:size="formSize"
status-icon
:validate-on-rule-change="false"
>
官方提供了現(xiàn)成的解決方案,原出處說的很清楚:

微信截圖_20241124145004.png
完整操作效果展示:

動畫.gif
四、結(jié)語
至此,問題1、2都完美解決,其實(shí)很多功能看文檔就能夠解決大部分問題了。
有任何問題的小伙伴可以留言交流~