formTable组件封装,添加表单验证
代码
<template>
<div>
<el-row style="margin-bottom: 20px">
<el-button type="primary" @click="handleAdd" color="#1F51F1">
<template #icon>
<img :src="useAssests('plus.png')" />
</template>
新增数据项
</el-button>
<el-button :disabled="!tableCheck.length" @click="handleBatchDelete"> 批量删除 </el-button>
</el-row>
<el-form :model="form" ref="formRef" :rules="rules">
<el-table
height="500"
@selection-change="(rows) => (tableCheck = rows)"
:data="form.tableData"
style="width: 100%"
cell-class-name="with-form-item"
>
<el-table-column type="selection" width="55" />
<el-table-column label="中文名称" prop="cn_name" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.cn_name'" :rules="rules.cn_name">
<el-input style="width: 148px" v-model="scope.row.cn_name" placeholder="请输入" clearable />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="英文名称" prop="en_name" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.en_name'" :rules="rules.en_name">
<el-input style="width: 148px" v-model="scope.row.en_name" placeholder="请输入" clearable />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="数据类型" prop="item_type" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.item_type'" :rules="rules.item_type">
<el-select v-model="scope.row.item_type" placeholder="请选择" style="width: 148px" clearable>
<el-option
:label="item.label"
:value="item.value"
v-for="(item, index) in item_type_list"
:key="index"
/>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="数据长度" prop="item_length" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.item_length'" :rules="rules.item_length">
<el-input
type="number"
style="width: 148px"
v-model.number="scope.row.item_length"
placeholder="请输入"
clearable
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="是否可为空" prop="is_let_null" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.is_let_null'" :rules="rules.is_let_null">
<el-select v-model="scope.row.is_let_null" placeholder="请选择" style="width: 148px" clearable>
<el-option label="可为空" :value="1" />
<el-option label="不可为空" :value="0" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="是否主键" prop="is_primary_key" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.is_primary_key'" :rules="rules.is_primary_key">
<el-select v-model="scope.row.is_primary_key" placeholder="请选择" style="width: 148px" clearable>
<el-option label="主键" :value="1" />
<el-option label="非主键" :value="0" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="默认值" prop="default_value" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.default_value'" :rules="rules.default_value">
<el-input style="width: 148px" v-model="scope.row.default_value" placeholder="请输入" clearable />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="字段描述" prop="item_msg" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.item_msg'" :rules="rules.item_msg">
<el-input style="width: 148px" v-model="scope.row.item_msg" placeholder="请输入" clearable />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="是否为字典项" prop="is_dictionary" width="160">
<template #default="scope">
<el-form-item :prop="'tableData.' + scope.$index + '.is_dictionary'" :rules="rules.is_dictionary">
<el-select v-model="scope.row.is_dictionary" placeholder="请选择" style="width: 148px" clearable>
<el-option label="主键" :value="1" />
<el-option label="非主键" :value="0" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="{ $index }">
<el-button type="primary" link @click="delTable($index)"> 删除 </el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { item_type_list } from '../../useAddDataResource'
const tableCheck = ref<any[]>([])
const formRef = ref<FormInstance>()
const form = reactive({
tableData: [] as any,
})
const rules = ref({
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
age: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
cn_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
en_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
item_type: [{ required: true, message: '请选择', trigger: 'blur' }],
item_length: [{ required: true, message: '请输入', trigger: 'blur' }],
is_let_null: [{ required: true, message: '请选择', trigger: 'blur' }],
is_primary_key: [{ required: true, message: '请选择', trigger: 'blur' }],
default_value: [{ required: true, message: '请输入', trigger: 'blur' }],
item_msg: [{ required: true, message: '请输入', trigger: 'blur' }],
is_dictionary: [{ required: true, message: '请选择', trigger: 'blur' }],
})
/**验证表单 */
function validForm() {
return new Promise<{ valid: boolean; data: any[] }>((resolve, reject) => {
formRef.value!.validate((valid) => {
resolve({ valid, data: form.tableData })
})
})
}
const handleBatchDelete = () => {
const ids = tableCheck.value.map((i) => i._uuid)
ids.map((uuid) => {
const index = form.tableData.findIndex((item) => item._uuid == uuid)
form.tableData.splice(index, 1)
})
}
const handleAdd = () => {
form.tableData.push({
_uuid: crypto.randomUUID(),
/**中文名称 */
cn_name: '',
/**英文名称 */
en_name: '',
/**数据类型 */
item_type: '',
/**数据长度 */
item_length: '',
/**是否可为空 */
is_let_null: '',
/**是否主键 */
is_primary_key: '',
/**默认值 */
default_value: '',
/**字段描述 */
item_msg: '',
/**是否为字典项 */
is_dictionary: '',
})
}
//删除
function delTable(i: number) {
form.tableData.splice(i, 1)
}
defineExpose({
/**验证表单 */
validForm,
})
onMounted(() => {})
</script>
<style lang="scss" scoped>
.with-form-item {
.cell {
.el-form-item {
margin: 0;
:deep(.el-form-item__error) {
position: static;
}
}
}
}
</style>
效果