el-form和el-table嵌套说明
① :model="formData" 给表单绑定数据,formData是表单的数据对象
② 表单数据对象formData中定义的tableData是表单内嵌套的表格显示数据
③ rules为表单绑定的校验规则
④ :prop="`tableData.${$index}.name`" 绑定传入Form 组件的 model 中对应的字段name
⑤ :rules="rules.name" 绑定表单校验规则
⑥ 整个html结构是一个大表单 el-form里边嵌套的el-table,而el-table中又嵌套了表单项 el-form-item支持编辑。
备注:大多情况下prop会按照惯有思维直接写入字段,而这里是动态绑定的,另外一定要记得每项动态写入rules来进行绑定表单校验
具体代码
<template><div class="layout-padding"><div class="layout-padding-auto" style="background-color: #fff;"><el-form :model="formData" ref="formRef" :rules="rules" :inline="true"><el-table :data="formData.tableData" border><el-table-column type="index" align="center" label="序号" width="65"></el-table-column><el-table-column label="姓名" prop="name" resizable align="center" header-align="center"><template #default="{ row, $index }"><el-form-item :prop="`tableData.${$index}.name`" :rules="rules.name"><el-input type="text" placeholder="请输入姓名" v-model="row.name"></el-input></el-form-item></template></el-table-column><el-table-column label="年龄" prop="age" resizable align="center" header-align="center"><template #default="{ row, $index }"><el-form-item :prop="`tableData.${$index}.age`" :rules="rules.age"><el-input type="text" placeholder="请输入年龄" v-model="row.age"></el-input></el-form-item></template></el-table-column><el-table-column label="性别" prop="sex" resizable align="center" header-align="center"><template #default="{ row, $index }"><el-form-item :prop="`tableData.${$index}.sex`" :rules="rules.sex"><el-input type="text" placeholder="请输入性别" v-model="row.sex"></el-input></el-form-item></template></el-table-column><el-table-column label="操作" resizable align="center" header-align="center" width="200"><template #default="{ row, $index }"><el-button type="primary" icon="ele-Plus" circle @click="addTable()"v-if="$index == 0"></el-button><el-button icon="ele-Minus" circle @click="delTable($index)" v-else></el-button></template></el-table-column></el-table><el-form-item class="footer"><el-button @click="reset">重置</el-button><el-button type="primary" @click="save">保存</el-button></el-form-item></el-form></div></div>
</template><script lang="ts">
import { toRefs, reactive, defineComponent, getCurrentInstance, } from 'vue';export default defineComponent({setup() {const { proxy }: any = getCurrentInstance();const data = reactive({formData: {tableData: [{ name: '张三', age: 18, sex: '' },{ name: '李四', age: 19, sex: '' },] as any[]},rules: {name: [{ required: true, message: '请输入姓名', trigger: 'blur' },],age: [{ required: true, message: '请输入年龄', trigger: 'blur' },],sex: [{ required: true, message: '请输入性别', trigger: 'blur' },],}});//保存const save = () => {//第一条数据不进行校验if (data.formData.tableData.length == 1 &&data.formData.tableData[0].name == '' &&data.formData.tableData[0].age == '' &&data.formData.tableData[0].sex == '') {//将rules中的校验required设置为falsedata.rules.name[0].required = false;data.rules.age[0].required = false;data.rules.sex[0].required = false;} else {//如果不是第一条数据,将rules中的校验required设置为true进行校验data.rules.name[0].required = true;data.rules.age[0].required = true;data.rules.sex[0].required = true;}proxy.$refs.formRef.validate((valid: any) => {//如果valid为true,表示校验通过,可以提交表单,调取接口进行保存if (valid) {proxy.$message.success("保存成功");} else {proxy.$message.warning("请填写完整的数据");}})}//重置const reset = () => {proxy.$refs.formRef.resetFields()data.formData.tableData = [{ name: '张三', age: 18, sex: '' },{ name: '李四', age: 19, sex: '' },]}//添加const addTable = () => {let newArr = [{name: '',age: '',sex: ''}]data.formData.tableData.push(...newArr)}//删除const delTable = (i: number) => {data.formData.tableData.splice(i, 1)}return {...toRefs(data), save, reset, addTable, delTable};}
})
</script><style lang="scss" scoped>
.footer {width: 100%;margin-top: 50px;:deep(.el-form-item__content) {justify-content: center;}
}
</style>
效果图