使用ElementUI中的el-table制作可编辑的表格

该文章已生成可运行项目,

在前端开发时,可能会需要用到可编辑的表格控件。一些原生的UI框架并不支持Table控件的可编辑功能,所以只能自己实现。

以下用Vue3+Element-Plus进行示例开发。

一、实现可编辑的单元格

我想要实现的效果是,鼠标移动到el-table的某行时,该行呈现可编辑效果。所以需要用到Table事件中的cell-mouse-entercell-mouse-leave。当鼠标移入时,将该行数据源编辑状态字段置为true,相应的单元格模板借助v-if绑定呈现出可编辑状态;鼠标移出时,再将状态字段置为false,隐藏编辑状态模板。

完整代码如下:

<template>
    <div>
        <el-table :data="dataList" @cell-mouse-enter="handleCellEnter" @cell-mouse-leave="handleCellLeave">
            <el-table-column type="index" width="50" />
            <el-table-column label="名称" prop="name" width="120">
                <template #default="scope">
                    <el-input v-if="scope.row.isEdit" class="cell-input" v-model="scope.row.name" />
                </template>
            </el-table-column>
            <el-table-column label="类型" prop="type" width="150">
                <template #default="scope">
                    <el-select v-if="scope.row.isEdit" class="cell-select" v-model="scope.row.type" placeholder="请选择">
                        <el-option v-for="item in TypeOptions" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                </template>
            </el-table-column>
            <el-table-column label="值" prop="value" width="150" />
        </el-table>
    </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue';

interface TempData {
    name: string,
    type: string,
    value: string,
    isEdit: boolean
}

const TypeOptions = [
    {
        value: 'Option1',
        label: 'Option1',
    },
    {
        value: 'Option2',
        label: 'Option2',
    },
    {
        value: 'Option3',
        label: 'Option3',
    }
]

const dataList = reactive<TempData[]>([
    {
        name: '张三',
        type: 'Option1',
        value: 'value',
        isEdit: false
    },
    {
        name: '李四',
        type: 'Option2',
        value: 'value',
        isEdit: false
    },
    {
        name: '王五',
        type: 'Option3',
        value: 'value',
        isEdit: false
    }
])

const handleCellEnter = (row: any, column: any, cell: any, event: any) => {
    row.isEdit = true
}

const handleCellLeave = (row: any, column: any, cell: any, event: any) => {
    row.isEdit = false
}
</script>
<style scoped>
.cell-input {
    height: 26px;
    margin-left: -10px;
}

:deep(.cell-select .el-select__wrapper) {
    height: 26px;
    min-height: 26px;
    margin-left: -11px;
}

:deep(.el-table .el-table__row) {
  height: 50px;
}
</style>

(说明:以上代码示例中,对编辑状态下的el-inputel-select样式进行了处理,使鼠标移入移出时不会出现明显的错位现象)

二、解决el-select下拉内容无法选择问题

通常el-select的下拉框会超出所在行的范围,因此当鼠标准备选择下拉框内容时,会因超出行的范围而触发取消编辑状态,el-select就会消失,这样一来永远无法选中下拉选项。

解决的方法便是记录el-select的状态,如果是下拉状态,则el-table的鼠标事件不要触发行状态更改。变更部分代码如下:

let canUpdateEditingState = false

const handleOptionVisibleChange = (isVisible: boolean, row: any) => {
    canUpdateEditingState = isVisible
    if (!isVisible) {
        row.isEdit = false
    }
}

const handleCellEnter = (row: any, column: any, cell: any, event: any) => {
    if (canUpdateEditingState) return
    row.isEdit = true
}

const handleCellLeave = (row: any, column: any, cell: any, event: any) => {
    if (canUpdateEditingState) return
    row.isEdit = false
}

然后给el-select绑定事件方法如下:

@visible-change="(arg: any) => handleOptionVisibleChange(arg, scope.row)"

三、解决el-input无法使用中文输入法的问题

由于输入中文时,输入法弹框也会触发el-tablecell-mouse-leave事件,导致刚打出字符,单元格的编辑状态便取消了。这就需要借助compositionstartcompositionend事件来屏蔽中文输入过程。原理和第二点类似,补充代码如下:

const handleCompositionStart = () => {
    canUpdateEditingState = true
}

const handleCompositionEnd = () => {
    canUpdateEditingState = false
}

给el-table增加事件绑定:

@compositionstart="handleCompositionStart" @compositionend="handleCompositionEnd"

2025.1.7 更新

关于第一点“实现可编辑的单元格”,使用Cell相关事件会响应过于频繁,性能很差。故本人后来改为了在row-click事件中将行置为可编辑状态,并取消其他行的编辑状态。

本文章已经生成可运行项目
### Element UI 的 `el-table` 组件实现行内编辑 为了实现在 `el-table` 中的行内编辑功能,可以通过监听特定事件并控制每一行的状态来切换输入模式和查看模式。下面是一个完整的示例说明如何通过点击编辑按钮触发行内编辑。 #### HTML 结构 ```html <template> <div id="app"> <el-table :data="tableData" style="width: 100%"> <!-- 定义表格--> <el-table-column label="日期" width="180"> <template slot-scope="scope"> <span v-if="!scope.row.edit">{{ scope.row.date }}</span> <el-input v-else v-model="scope.row.date"></el-input> </template> </el-table-column> <el-table-column label="姓名" width="180"> <template slot-scope="scope"> <span v-if="!scope.row.edit">{{ scope.row.name }}</span> <el-input v-else v-model="scope.row.name"></el-input> </template> </el-table-column> <el-table-column label="地址"> <template slot-scope="scope"> <span v-if="!scope.row.edit">{{ scope.row.address }}</span> <el-input v-else v-model="scope.row.address"></el-input> </template> </el-table-column> <el-table-column fixed="right" label="操作" width="120"> <template slot-scope="scope"> <el-button @click.prevent="editRow(scope.$index)" type="text">编辑</el-button> <el-button @click.prevent="saveRow(scope.$index)" type="text">保存</el-button> </template> </el-table-column> </el-table> </div> </template> ``` #### JavaScript 部分 ```javascript <script> export default { data() { return { tableData: [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', edit: false }, { date: '2016-05-02', name: 'John', address: 'New York No. 1 Lake Park', edit: false } ] }; }, methods: { // 编辑当前行 editRow(index) { this.tableData[index].edit = true; }, // 保存修改后的数据 saveRow(index) { this.tableData[index].edit = false; console.log('Updated Data:', this.tableData); // 此处可加入API调用来提交更改到服务器 } } }; </script> ``` 此代码片段展示了怎样利用 Vue.jsElement UI 来创建一个支持行内编辑的表格[^1]。当用户点击“编辑”按钮时,对应行进入编辑状态;而点击“保存”则会结束编辑并将新值应用回原始对象上。此外,在实际项目中可能还需要考虑验证逻辑以及向后台发送更新请求等功能扩展[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值