<template #remarkColumn="{row}"> <div class="inline-data-edit-box"> <a-input size="small" :disabled="!row.editable" v-model:value="row.remark" placeholder="请输入备注" /> <a-button size="small" type="primary" ghost @click="editInlineTableData(row,$event)">编辑</a-button> </div> </template>
复制
为表格添加行编辑功能时,需要实现以下交互逻辑:
1、点击"编辑"按钮后切换单元格为可编辑状态;
2、输入完成后点击保存或其他地方关闭单元格的可编辑状态;
需求2比较好做,直接为输入框注册一个@blur事件即可,需求1需要获取输入框元素,然后调用元素的focus方法,
难点在于如何精准获取当前单元格内的输入框元素
思路1:
为每个input绑定动态class名,然后在表格容器元素中按照类名查找
<a-input size="small" :class="'editable-input-'+row.id" :disabled="!row.editable" v-model:value="row.remark" placeholder="请输入备注" />
复制
function editInlineTableData(row,evt) { const tableWrapper = document.querySelector('.bottom-wrapper') const target = tableWrapper.querySelector(`input.editable-input-${row.id}`) as HTMLInputElement target.focus() }
复制
缺点:
使用querySelector查询元素操作性能开销较大
思路2:
通过点击的事件对象参数,得到target属性对应的元素,然后通过该元素与input元素的关系获取input
function editInlineTableData(row,evt) { const inputElement = evt.target.nodeName === 'SPAN' ? evt.target.parentNode.previousSibling : evt.target.previousSibling nextTick(()=>{ inputElement.focus() }) }
复制
缺点:
如果点击的区域内的元素嵌套层级过多,需要判断的元素也多
思路3(推荐):
使用vue的指令,当input元素创建时,自动获得焦点
const vFocus = { mounted: (el) => { el.querySelector('.ant-input')?.focus() } }
复制