<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()
}
}