场景:在项目的开发过程中,经常使用到表单中嵌套着可编辑的表格,这个时候就需要表单的双重校验。
本文栗子为二次封装动态增减的可编辑表格,并实现表表单的双重校验
ps:由于实现的数据比较多,当前栗子为比较脱敏的,省略了一些字段,换汤不换药。
子组件 variableList.vue
<template>
<article class="TPL_variable-list-container">
<el-form
ref="variableListForm"
:model="formData"
>
<el-table
v-show="formData.variableList.length"
:data="formData.variableList"
border
style="width: 100%"
class="form-item-content variable_tabel"
>
<!-- 变量-变量ID -->
<el-table-column
label="id"
class="table-item variable-item-id variable-id"
>
<template slot-scope="scope">
<el-form-item
:prop="`variableList.${scope.$index}.id`"
:rules="variableRules.id"
>
<el-input v-model.number="scope.row.id" class="table-item-content variable-id_input" />
</el-form-item>
</template>
</el-table-column>
<!-- 变量-变量名 -->
<el-table-column
label="name"
class="table-item variable-item-name variable-name"
>
<template slot-scope="scope">
<el-form-item
:prop="`variableList.${scope.$index}.name`"
:rules="variableRules.name"
>
<el-input v-model="scope.row.name" class="table-item-content variable-name_input" />
</el-form-item>
</template>
</el-table-column>
<!-- 变量-编辑 -->
<el-table-column
:label="variableLabels.operator"
class="table-item variable-item-operator variable-operator"
width="60"
>
<template slot-scope="scope">
<i class="el-icon-remove remove" @click="removeVariable(scope.$index)" />
</template>
</el-table-column>
</el-table>
</el-form>
<!-- 添加变量按钮 -->
<el-link
class="form-item-content"
type="primary"
:underline="false"
icon="el-icon-circle-plus"
@click.native="addVariable"
>
添加变量
</el-link>
</article>
</template>
<script>
export default {
name: 'VariableList',
props: {
/**
* 父组件model必须为object
* 因为table中嵌套的form-item,所以table外层必须有el-form,el-form必须model,校验才生效
* 且value默认传入的variableList属性,与table的绑定
* */
value: { type: Object, default: () => {} }
},
data () {
return {
formData: {
variableList: [] // 默认有该属性,且该属性名定义为variableList
},
variableRules: {
id: [{
required: true,
message: `请填入变量id`,
trigger: ['blur', 'change']
},
{
type: 'number',
message: '请输入数字'
}],
name: [{
required: true,
message: `请填入变量名`,
trigger: ['blur', 'change']
}]
}
}
},
watch: {
value: {
immediate: true,
handler(newV) {
this.formData = newV
}
}
},
methods: {
// 添加变量
addVariable() {
const newVariable = {
id: '',
name: ''
}
this.pushVariable(this.formData.variableList, newVariable)
},
// 移除变量
removeVariable(id) {
this.spliceVariable(this.formData.variableList, id)
},
// 公共方法 - 添加变量
pushVariable(list, obj) {
list.push(obj)
},
// 公共方法 - 移除变量
spliceVariable(list, id) {
list.splice(id, 1)
}
}
}
</script>
子组件的使用
<template>
<el-form
ref="fatherForm"
:model="dataForm"
:rules="rules"'
:label-width="'120px'"
label-position="'right'"
class="TPL_deploy_form"
>
<el-form-item
label="name"
class="form-item item-space-name"
prop="name"
>
<el-input
v-model="dataForm.name"
class="form-item-content content_input name_input"
/>
</el-form-item>
<el-form-item
label="变量"
class="form-item item-variable"
>
<!-- deployTplForm 中必须有属性variableList数组(子组件中自定义的,这里传入的object需要包含该字段) -->
<!-- 使用子组件 :传入一个ref用于校验时获取子组件校验结果-->
<variable-list ref="childrenForm" v-model="dataForm" />
</el-form-item>
<!-- footer -->
<el-form-item class="form-item footer-conatiner">
<el-button
type="primary"
icon="el-icon-plus"
@click="OnSubmit"
>
提交
</el-button>
</el-form-item>
</el-form>
</template>
<script>
// 引入子组件
import variableList from '@/business/tmp/variableList/index.vue'
export default {
components: {
variableList
},
data() {
return {
dataForm: {
name: '',
variableList: []
},
}
},
methods: {
// 表单校验:可用于多个表单同时校验
getFormValidPromise(form) {
return new Promise((resolve, reject) => {
form.validate((res) => {
resolve(res)
})
})
},
// 提交表单
OnSubmit() {
const father_form = this.$refs.fatherForm // 父表单
// 获取子组件的表单,childrenForm:使用子组件时传的ref;variableListForm:子组件中el-form的ref
const children_form = this.$refs.childrenForm.$refs.variableListForm
Promise.all(
[father_form, children_form].map(this.getFormValidPromise)).then((res) => {
const validateResult = res.every(item => !!item)
if (validateResult) {
console.log('两个表单都校验通过')
} else {
console.log('两个表单未校验通过')
}
})
},
}
}
</script>