期望通过每一次分享,让技术的门槛变低,落地更容易。 —— around
旨在解决项目过程中遇到触发el-form验证失效,多级对象属性如何编写验证规则,动态表单控件如何处理。项目web端使用的是vue3+element plus,下面代码介绍等相关内容均以vue3+ts语法描述。
样例如下代码所示,已贴全部代码,后续说明以该代码所示
<template>
<div class="system-add-message-container">
<el-dialog title="加入 面试管理-已邀约" v-model="isShowDialog" width="500px">
<el-form ref="userFormRef" :model="ruleForm" :rules="rules" size="default" label-width="110px">
<el-form-item label="归属人" prop="belonger">
<el-input v-model="ruleForm.belonger" disabled>el-input>
el-form-item>
<el-form-item label="面试时间" prop="child.interviewTime">
<el-date-picker class="w100" v-model="ruleForm.child.interviewTime" type="datetime" placeholder="请选择面试时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
el-form-item>
el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel" size="default">取 消el-button>
<el-button v-loading="loading" type="primary" @click="onSubmit" size="default">提 交el-button>
span>
template>
el-dialog>
div>
template>
<script lang="ts">
import { reactive, toRefs, onMounted, defineComponent, ref, getCurrentInstance } from 'vue';
import { recruimentApi } from '/@/api/recruiment/recruiment';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
export default defineComponent({
name: 'copyUser',
setup(props, context) {
const { proxy } = <any>getCurrentInstance();
const stores = useUserInfo();
const { userInfos } = storeToRefs(stores);
const userFormRef = ref();
const belongerIdRef = ref();
const state = reactive({
loading: false,
isShowDialog: false,
ruleForm: {
belonger: '', //归属人
child: {
interviewTime: '',
},
},
belongerData: [], //初始化数据
selectRow: {} as any, //选中行对象
positionOptions: [] as any[],
rules: {
positionId: [{ required: true, message: '请选择岗位', trigger: 'blur' }],
child:{
interviewTime: [{ required: true, message: '请选择面试时间', trigger: 'blur' }],
},
},
});
// 打开弹窗
const openDialog = (row: any) => {
state.ruleForm = {
belonger: '', //归属人
child: {
interviewTime: '',
},
};
};
// 新增
const onSubmit = async () => {
state.loading = true;
proxy.$refs['userFormRef'].validate(async (valid: any) => {
if (valid) {
//验证通过
}
state.loading = false;
});
};
return {
userFormRef,
belongerIdRef,
openDialog,
onSubmit,
...toRefs(state),
};
},
});
script>
通常表单验证失效有三类原因,ref
名称不对、model
绑定有问题、prop
编写错误,正确写法见下挨个检查即可保证是正确的。
<el-form ref="userFormRef" :model="ruleForm" :rules="rules">
<el-form-item label="归属人" prop="belonger">
<el-input v-model="ruleForm.belonger" disabled>el-input>
el-form-item>
el-form>
el-form
表单属性时,请使用:model
而不是使用v-model
。el-form-item
标签,需要注意的是它将直接绑定属性名,原则上按照顶级为model
绑定对象,依次填写下级需要参与验证的属性名即可,这里额外要注意的是,对于超过2层级的对象属性封装,需要保持:model与:rules的属性名同层级关系
el-form
的ref属性声明的名称为字符串上述值为ref="userFormRef"
,在el-form
表单验证时,方法为如下内容,注意$refs['userFormRef']
部分直接使用的是字符串填写模式proxy.$refs['userFormRef'].validate(async (valid: any) => {
if (valid) {
//验证通过
}
state.loading = false;
});
el-form
声明ref="userFormRef"
,需要通过方法进入表单提交,本方式适用于多el-form
动态验证的模式。注意看下面的按钮click事件onSubmit('userFormRef')
,将ref的字符串声明传递进入提交方法,通过方法传参formName
与表单验证方法绑定完成指定表单验证<el-button @click="onSubmit('userFormRef')" size="default">提 交</el-button>
......
const onSubmit = async (formName: string) => {
proxy.$refs[formName].validate(async (valid: any) => {
if (valid) {
//验证成功
}
});
};
综上,100%可以解决
表单验证功能失效的问题。
form
绑定的model结构如下:
ruleForm: {
belonger: '',
child: {
interviewTime: '',
},
},
如上图,需要对interviewTime
属性对应空间添加表单校验,页面控件绑定prop="interviewTime"
已经是不正确的了,由于:model="ruleForm"
,默认填写下面一层关系的属性名可以直接写,但多层级必须带上除ruleForm
外的完整路径,应是child.interviewTime
,同时在调整rules中的层级结构,否则无法生效,参考下面正确结果
<el-form-item label="面试时间" prop="child.interviewTime">
<el-date-picker v-model="ruleForm.child.interviewTime" type="datetime" />
el-form-item>
form
绑定的rules结构如下:
rules: {
belonger: [{ required: true, message: '请选择', trigger: 'blur' }],
child:{
interviewTime: [{ required: true, message: '请选择面试时间', trigger: 'blur' }],
},
},
本功能还未做完,但这样应该是可行的,可以直接在产生动态表单的el-form-item
中设置prop为传参形态,见下文
<el-form-item :prop="{'start'+state.index + 'Count'}">
后续在对应的rules
中以初始化方式同样更新迭代一次赋值结果集,即可保证form表单支持动态属性名的校验。
更多el-form
表单使用问题后续追加。