<template>
<div class="editable-table">
<el-button @click="handleAddRow" type="primary">添加行</el-button>
<el-button @click="handleSubmit" type="success">提交</el-button>
<el-table :data="tableData" border style="width: 100%">
<!-- 姓名列 -->
<el-table-column prop="name" label="姓名">
<template #default="scope">
<el-input
v-model="scope.row.name"
@blur="validateField(scope.row, 'name')"
:class="{ 'is-error': scope.row.errors.name }"
/>
<div class="error-text" v-if="scope.row.errors.name">
{{ scope.row.errors.name }}
</div>
</template>
</el-table-column>
<!-- 年龄列 -->
<el-table-column prop="age" label="年龄">
<template #default="scope">
<el-input
v-model.number="scope.row.age"
@blur="validateField(scope.row, 'age')"
:class="{ 'is-error': scope.row.errors.age }"
/>
<div class="error-text" v-if="scope.row.errors.age">
{{ scope.row.errors.age }}
</div>
</template>
</el-table-column>
<!-- 邮箱列 -->
<el-table-column prop="email" label="邮箱">
<template #default="scope">
<el-input
v-model="scope.row.email"
@blur="validateField(scope.row, 'email')"
:class="{ 'is-error': scope.row.errors.email }"
/>
<div class="error-text" v-if="scope.row.errors.email">
{{ scope.row.errors.email }}
</div>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作">
<template #default="scope">
<el-button
@click="handleDelete(scope.$index)"
type="danger"
size="small"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
// 验证规则
const rules = {
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
age: [
{ required: true, message: '年龄不能为空' },
{ type: 'number', message: '年龄必须为数字', trigger: 'blur' },
{ validator: (val) => val >= 0, message: '年龄不能为负数' }
],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
]
}
// 表格数据
const tableData = ref([
{
name: '',
age: null,
email: '',
errors: { name: '', age: '', email: '' }
}
])
// 添加新行
const handleAddRow = () => {
tableData.value.push({
name: '',
age: null,
email: '',
errors: { name: '', age: '', email: '' }
})
}
// 删除行
const handleDelete = (index) => {
tableData.value.splice(index, 1)
}
// 字段验证
const validateField = (row, field) => {
row.errors[field] = ''
const value = row[field]
const fieldRules = rules[field]
for (const rule of fieldRules) {
if (rule.required && !value) {
row.errors[field] = rule.message
return
}
if (rule.type === 'number' && typeof value !== 'number') {
row.errors[field] = rule.message
return
}
if (rule.type === 'email' && !/^\w+@\w+\.\w+$/.test(value)) {
row.errors[field] = rule.message
return
}
if (rule.validator && !rule.validator(value)) {
row.errors[field] = rule.message
return
}
}
}
// 提交验证
const handleSubmit = () => {
let isValid = true
tableData.value.forEach(row => {
Object.keys(rules).forEach(field => {
validateField(row, field)
if (row.errors[field]) isValid = false
})
})
if (isValid) {
ElMessage.success('验证通过,提交成功!')
// 这里可以添加实际提交数据的逻辑
} else {
ElMessage.error('请检查表单中的错误')
}
}
</script>
<style scoped>
.editable-table {
padding: 20px;
}
.error-text {
color: #ff4d4f;
font-size: 12px;
line-height: 1;
padding-top: 4px;
}
.is-error {
:deep(.el-input__wrapper) {
box-shadow: 0 0 0 1px var(--el-color-danger) inset;
}
}
</style>