vue3.2 + element-plus 表单嵌套表格实现动态表单验证
借鉴了这位兄弟的思想,进行了优化和vue3.2语法糖改造:https://blog.csdn.net/weixin_45295253/article/details/115582504
实现:
<template>
<el-form ref="formRef" :model="form">
<el-table ref="tableRef" class="table-class" :data="form.tableData" border style="width: 100%">
<el-table-column type="index" label="序号" width="55"></el-table-column>
<el-table-column v-for="(item, index) in tableList" :key="index" :width="item.width">
<template #header>
<span>
<span v-if="item.prop" class="required">*</span>
{{ item.label }}
</span>
</template>
<template #default="scoped">
<el-form-item :prop="`tableData[${scoped.$index}][${item.prop}]`" :rules="rules[item.prop]">
<el-input
type="text"
placeholder="输入姓名"
:title="scoped.row[item.prop]"
v-model="scoped.row[item.prop]"
></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="120">
<template #default="scoped">
<span class="text-btn" @click="delTableRowFn(scoped.$index)">删除</span>
</template>
</el-table-column>
</el-table>
</el-form>
<el-button @click="sumbit">校验</el-button>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
const title = '123'
const formRef = ref<FormInstance>(null)
const tableRef = ref(null)
const form = ref({
tableData: [
{
realname: '1',
realname1: ''
}
]
})
const tableList = reactive([
{
label: '姓名',
width: '200',
prop: 'realname'
},
{
label: '姓名',
width: '200',
prop: 'realname1'
}
])
const rules = reactive<FormRules>({
realname: [
{
required: true,
message: '',
trigger: 'blur'
}
],
realname1: [
{
required: true,
message: '123',
trigger: 'blur'
}
]
})
const delTableRowFn = (val: any) => {
console.log(val)
}
const sumbit = async () => {
await formRef.value.validate((valid, fields) => {
if (valid) {
console.log('submit!')
} else {
console.log('error submit!', fields)
}
})
}
</script>
<style lang="scss" scoped>
.required {
color: red;
}
.text-btn {
text-align: center;
color: #0c64eb;
margin: 0 8px;
cursor: pointer;
}
:deep(.table-class .el-form-item) {
margin-bottom: 0px;
}
:deep(.table-class .el-input__wrapper) {
padding: 0px;
border-radius: 0;
box-shadow: unset;
}
:deep(.el-form-item.is-error .el-input__wrapper) {
box-shadow: 0 0 0 1px var(--el-color-danger) inset;
}
:deep(.el-table .cell) {
padding: 0px;
text-align: center;
}
:deep(.table-class .el-input) {
margin-left: 1px;
}
:deep(.table-class .el-input__inner) {
line-height: 23px;
--el-input-inner-height: 40px;
text-align: center;
}
:deep(.table-class .el-table__body .el-table__row .el-table__cell) {
padding: 0px;
}
</style>