君子之交淡如水|

庄周de蝴蝶

园龄:6年9个月粉丝:0关注:0

Vue + ElementUI 实现可编辑表格及校验

效果

20230801161207.gif 也可以通过码上掘金继续查看(效果有所差距)。

完整代码见文末

实现思路

  1. 使用两个表单分别用于实现修改和新增处理。

  2. 通过一个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
    }
  3. 通过隐藏表头实现新增表格和修改表格的合并,同时表格数据只有addRow

    <el-table :data="[addRow]" :show-header="false">
    ...
    </el-table>

实现细节讲解

  1. 当无数据时只展示新增行:

    image-20230801162740429

    通过设置以下样式即可:

    /deep/ .el-table__empty-block {
    display: none;
    }
  2. 新增或者修改数据行时增加行高用于显示校验信息:

    动画

    行高通过以下样式进行控制,不处于新增或者修改状态时设置为 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>

本文作者:庄周de蝴蝶

本文链接:https://www.cnblogs.com/butterfly-fish/p/17762265.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   庄周de蝴蝶  阅读(1296)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起