效果
完整代码见文末
实现思路
-
使用两个表单分别用于实现修改和新增处理。
-
通过一个
editIndex
变量判断是否是编辑状态来决定是否展示输入框,当点击指定行的修改后进行设置即可:<el-table-column v-for="(column, index) in columns" :key="index" :label="column.label" :prop="column.prop" align="center"> <template #default="{ row, $index }"> <div v-if="$index === editIndex" class="validate-info"> <el-form-item :prop="column.prop"> <el-input v-model="editRow[column.prop]"/> </el-form-item> </div> <span v-else> <span>{{ row[column.prop] }}</span> </span> </template> </el-table-column>
edit(row, index) { if (this.editIndex > -1) { this.$message.warning('请先完成修改中的行') return } this.editRow = {...row} this.editIndex = index }
-
通过隐藏表头实现新增表格和修改表格的合并,同时表格数据只有
addRow
:<el-table :data="[addRow]" :show-header="false"> ... </el-table>
实现细节讲解
-
当无数据时只展示新增行:
通过设置以下样式即可:
/deep/ .el-table__empty-block { display: none; }
-
新增或者修改数据行时增加行高用于显示校验信息:
行高通过以下样式进行控制,不处于新增或者修改状态时设置为 0 即可:
.add-table /deep/ .el-form-item { margin: 18px 0; }
为了在修改时只设置修改行的行高,只需要只对输入框绑定样式即可:
<div v-if="$index === editIndex" class="validate-info"> <el-form-item :prop="column.prop"> <el-input v-model="editRow[column.prop]"/> </el-form-item> </div>
完整代码
<template>
<div class="app">
<el-form
ref="editableForm"
:model="editRow"
:rules="rules"
label-width="0"
:show-message="true"
class="editable-table">
<el-table :data="tableData">
<el-table-column
v-for="(column, index) in columns"
:key="index"
:label="column.label"
:prop="column.prop"
align="center">
<template #default="{ row, $index }">
<div v-if="$index === editIndex" class="validate-info">
<el-form-item :prop="column.prop">
<el-input v-model="editRow[column.prop]"/>
</el-form-item>
</div>
<span v-else>
<span>{{ row[column.prop] }}</span>
</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template #default="{ row, $index }">
<el-form-item>
<template v-if="$index === editIndex">
<el-button type="success" size="mini" plain @click="save">保存</el-button>
<el-button type="info" size="mini" plain @click="cancel">取消</el-button>
</template>
<template v-else>
<el-button
type="primary"
size="mini"
plain
@click="edit(row, $index)">
修改
</el-button>
<el-popconfirm
title="是否确认删除?"
@confirm="deleteRow($index)"
style="margin-left: 10px;">
<el-button slot="reference" type="danger" size="mini" plain>删除</el-button>
</el-popconfirm>
</template>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
<el-form
ref="addForm"
:model="addRow"
:rules="rules"
label-width="0"
:show-message="true"
class="add-table">
<el-table :data="[addRow]" :show-header="false">
<el-table-column
v-for="(column, index) in columns"
:key="index"
:label="column.label"
:prop="column.prop"
align="center">
<template #default="{ row }" class="validate-info">
<div class="validate-info">
<el-form-item :prop="column.prop">
<el-input v-model="addRow[column.prop]"/>
</el-form-item>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="200px" align="center">
<template #default="{ row }">
<el-form-item>
<el-button type="success" size="mini" plain @click="add(row)">新增</el-button>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
// 表格数据
tableData: [
{
username: '张三',
address: '北京'
},
{
username: '李四',
address: '上海'
}
],
//配置列
columns: [
{
label: '用户名',
prop: 'username'
},
{
label: '地址',
prop: 'address'
}
],
// 规则
rules: {
username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
address: [{required: true, message: '请输入地址', trigger: 'blur'}],
},
// 当前编辑行下标
editIndex: -1,
// 当前编辑行
editRow: {
username: '',
address: ''
},
// 新增行
addRow: {
username: '',
address: ''
}
}
},
methods: {
save() {
this.$refs.editableForm.validate((valid) => {
if (valid) {
this.tableData.splice(this.editIndex, 1, { ...this.editRow })
this.editIndex = -1
this.$message.success('修改成功')
}
return valid
})
},
cancel() {
this.editIndex = -1
},
edit(row, index) {
if (this.editIndex > -1) {
this.$message.warning('请先完成修改中的行')
return
}
this.editRow = {...row}
this.editIndex = index
},
add(row) {
if (this.editIndex > -1) {
this.$message.warning('请先完成修改中的行')
return
}
this.$refs.addForm.validate((valid) => {
if (valid) {
this.addRow = {}
this.tableData.push({ ... row})
this.$message.success('新增成功')
}
return valid
})
},
deleteRow(index) {
this.tableData.splice(index, 1)
this.$message.success('删除成功!');
}
}
}
</script>
<style scoped lang="less">
.app {
padding: 20px;
/deep/ .el-form-item {
margin-bottom: 0;
}
}
.validate-info {
/deep/ .el-form-item {
margin: 18px 0;
}
}
.editable-table {
/deep/ .el-table__empty-block {
display: none;
}
}
.editable-table, .add-table {
width: 60%;
margin: 0 auto;
}
</style>