业务场景碰到不同的Tab展示不同的表单,最后点击提交的时候,一起校验。
先看下表单的template
<!-- 基础信息-->
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="120px"
class="demo-ruleForm mt-20"
:size="formSize"
status-icon
v-show="selectedTab == '基础信息'"
>
<el-form-item label="所属层级" prop="dwplId">
<el-select
v-model="ruleForm.dwplId"
placeholder="请选择"
@change="onLevelChange"
class="w-full"
>
<el-option
v-for="item in levelArr[0]?.childr"
:key="item.id"
:label="item.levelName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库" prop="databases">
<el-select
v-model="ruleForm.databases"
placeholder="请选择"
class="w-full"
:disabled="!ruleForm.dwplId"
>
<el-option
v-for="item in dataBaseList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="主题域" prop="subject">
<el-select v-model="ruleForm.subject" placeholder="请选择" class="w-full">
<el-option
v-for="item in subjectList"
:key="item.id"
:label="item.subjectName"
:value="item.subjectName"
/>
</el-select>
</el-form-item>
<el-form-item label="表英文名" prop="tableName">
<el-input v-model="ruleForm.tableName" />
</el-form-item>
<el-form-item label="描述" prop="remark">
<el-input v-model="ruleForm.remark" type="textarea" />
</el-form-item>
<!-- <el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">
Create
</el-button>
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
</el-form-item> -->
</el-form>
<!-- 字段信息表单 这个一个动态表单 用户可以增删表单字段 -->
<el-form
ref="formRef2"
:model="form2"
:rules="rules2"
label-width="150px"
class="mt-20"
v-show="selectedTab == '字段信息'"
label-position="top"
>
<el-row v-for="(item, index) in form2.fields" :key="index" :gutter="20">
<el-col :span="6">
<el-form-item
label="列名"
:prop="`fields[${index}].name`"
:rules="rules2.name"
>
<el-tooltip
placement="top"
effect="dark"
content="只能输入字母、数字、下划线,不超过50个字符"
>
<el-input
v-model.trim="item.name"
clearable
maxlength="50"
placeholder="请输入"
>
</el-input>
</el-tooltip>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="类型"
:prop="`fields[${index}].type`"
:rules="rules2.type"
>
<el-select
v-model="item.type"
placeholder="请选择"
style="width: 100%"
clearable
>
<el-option
v-for="item in typeList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="描述" :prop="`fields[${index}].remark`">
<el-tooltip
placement="top"
effect="dark"
content="列名的中文描述,不超过50个字符"
>
<el-input
v-model.trim="item.remark"
clearable
maxlength="50"
placeholder="请输入"
>
</el-input>
</el-tooltip>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="操作">
<div class="opera u-f u-f-ac">
<i-ep-top
class="icon mr-15 cursor-pointer"
style="font-size: 17px"
:class="{ disable: index === 0 }"
@click="handleMoveUp(index)"
/>
<i-ep-bottom
class="icon mr-15 cursor-pointer"
:class="{ disable: index === form2.fields.length - 1 }"
@click="handleDown(index)"
/>
<i-ep-delete
class="icon delete cursor-pointer"
@click="handleDeleteSub(index)"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="handleAddSubject">添加</el-button>
</el-form-item>
</el-form>
<!-- 高级信息 -->
<el-form
ref="ruleFormRef3"
:model="ruleForm3"
:rules="rules3"
label-width="120px"
class="demo-ruleForm mt-20"
:size="formSize"
status-icon
v-show="selectedTab == '高级信息'"
>
<el-form-item label="存储格式" prop="saveFormat">
<el-select v-model="ruleForm3.saveFormat" placeholder="请选择">
<el-option
v-for="item in saveFormatList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="存储类型" prop="saveType">
<el-select v-model="ruleForm3.saveType" placeholder="请选择">
<el-option
v-for="item in saveTypeList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="列分割符" prop="fieldCharacter">
<el-tooltip
placement="top"
effect="dark"
content="用来对数据的字段进行分割,必须和原表列分隔符一致,否则数据接入失败"
>
<el-select v-model="ruleForm3.fieldCharacter" placeholder="请选择">
<el-option
v-for="item in separatorList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item label="列转义字符" prop="escapeCharacter">
<el-tooltip
placement="top"
effect="dark"
content="过滤字段中的特殊符号。用户自定义符号,默认值为空"
>
<el-input v-model="ruleForm3.escapeCharacter" />
</el-tooltip>
</el-form-item>
<el-form-item label="collection分割符" prop="collectionCharacter">
<el-input v-model="ruleForm3.collectionCharacter" type="textarea" />
</el-form-item>
<el-form-item label="map-kv分割符" prop="kvCharacter">
<el-input v-model="ruleForm3.kvCharacter" type="textarea" />
</el-form-item>
</el-form>
看下表单定义的校验规则
// 表单1
const rules = reactive<FormRules<RuleForm>>({
dwplId: [{ required: true, message: '请选择层级', trigger: 'change' }],
databases: [
{
required: true,
message: '请选择数据库',
trigger: 'change',
},
],
subject: [
{
required: true,
message: '请选择主题',
trigger: 'change',
},
],
tableName: [
{
required: true,
message: '请输入表名',
trigger: 'blur',
},
],
remark: [{ required: false, message: '请输入描述', trigger: 'blur' }],
})
// 表单2
const form2 = reactive({
fields: [
{
name: '',
type: '',
remark: '',
isDel: 0,
sort: 1,
},
],
})
const rules2 = reactive({
name: [
{ required: true, message: '列名不能为空', trigger: 'blur' },
{ validator: noSpecial, trigger: 'blur' },
],
type: [{ required: true, message: '类型不能为空', trigger: 'change' }],
})
通过Promise.all来校验多个表单
const handleSubmit = async () => {
try {
// 校验基础信息
const validateBasic = async () => {
return new Promise((resolve, reject) => {
ruleFormRef.value?.validate(valid => {
if (valid) {
console.log('success1')
resolve(true) // Resolve with true if validation succeeds
} else {
console.log('failures1')
reject(false) // Reject with false if validation fails
}
})
})
}
// 字段信息
const validateColumn = () => {
return new Promise((resolve, reject) => {
formRef2.value?.validate(valid => {
if (valid) {
console.log('success2')
resolve(true)
} else {
console.log('failures2')
reject(false)
}
})
})
}
return Promise.all([validateBasic(), validateColumn()])
.then(async ([basicValid, columnValid]) => {
// 校验通过 调用接口保存表单数据
if (basicValid && columnValid) {
let params: any = {
projectId: commonStore.currentProject.id,
base: ruleForm.value,
fields: form2.fields,
conf: ruleForm3.value,
}
if (props.row) {
params.id = props.row.id
}
await fetchTableManagementUpdate(params)
console.log('Both forms are validated successfully')
return Promise.resolve()
} else {
console.log('One or both validations failed.')
return Promise.reject('表单验证失败')
}
})
.catch(error => {
console.error('Error occurred111111:', error)
return Promise.reject('表单验证失败')
})
// Do something if both forms are valid
} catch (error) {
console.log('Error during form validation:', error.message)
// Handle validation errors
}
}
// 父组件调用
const handleSubmit = () => {
editRef.value?.handleSubmit().then(() => {
showEdit.value = false
proxy?.$message({
message: '操作成功',
duration: 1000,
type: 'success',
})
handleSearch()
})
}
由于
validate()返回一个Promise,所以用new Promise((resolve, reject)在里面校验