效果图:
需求:
- 有remark数据的,点击后显示弹窗,可以直接编辑
- 无数据的显示empty,点击后添加信息
页面代码:
<el-table-column
label="Remark"
prop="note"
show-overflow-tooltip
min-width="76"
>
<template #header>
<el-tooltip content="Remark">
<span>Remark</span>
</el-tooltip>
</template>
<template #default="scope">
<el-popover
:ref="setPopoverRef(scope.row)"
placement="bottom"
:width="350"
trigger="click"
v-model:visible="scope.row.popoverVisible"
@show="handlePopoverShow(scope.row)"
>
<template #reference>
<span class="editable-text" @click.stop>
{{ scope.row.note?.length > 0 ? scope.row.note : 'Empty' }}
</span>
</template>
<div style="margin-bottom: 10px;">
<el-input
v-model="scope.row.editingNote"
type="textarea"
:rows="4"
placeholder="Enter remark"
clearable
/>
</div>
<div style="text-align: right; margin: 0; float: right">
<el-button
size="small"
type="primary"
@click="handleRemarkSave(scope.row)"
>
<el-icon><Select /></el-icon>
</el-button>
<el-button
size="small"
@click="handleRemarkCancel(scope.row)"
>
<el-icon>
<CloseBold />
</el-icon>
</el-button>
</div>
</el-popover>
</template>
</el-table-column>
逻辑代码:
// 存储popover引用
const popoverRefs = ref({})
// 设置popover引用
const setPopoverRef = (row) => (el) => {
if (el) {
popoverRefs.value[row.id] = el
}
}
const handlePopoverShow = (row) => {
if (row.editingNote === undefined || row.editingNote === null) {
row.editingNote = row.note || '';
}
};
// 保存备注
const handleRemarkSave = async (row) => {
// 更新本地 note 字段
row.note = row.editingNote || '';
try {
await axios.post('/api/xxxxxxxxxxx', {
id: row.id,
note: row.note
}, {
headers: {
'Content-Type': 'application/json'
}
});
// 可选:提示用户保存成功
ElMessage.success('Remark saved successfully');
} catch (error) {
// 如果失败,回滚 note 并提示错误
console.error('Failed to save remark:', error);
ElMessage.error('Failed to save remark');
// 回滚更改(可选)
row.note = row.note; // 原值不变
} finally {
// 关闭 popover
row.popoverVisible = false;
// 清理编辑状态
delete row.editingNote;
}
};
// 取消编辑
const handleRemarkCancel = (row) => {
// 关闭popover
row.popoverVisible = false
// 清空编辑内容
delete row.editingNote
}