应用效果:从第一行输入1,按回车,聚焦到第二行输入2,按回车,聚焦到第三行……
一、通过元素 id,聚焦到下一行的输入框
关键技术点:
1、动态设置元素 id 属性为::id="`input-apply-amount-${(option as IReagentOption).id}`"
2、设置回车监听:@keyup.enter.native="onEnterPressDown((option as IReagentOption).id)"
<el-input
......
:id="`input-apply-amount-${(option as IReagentOption).id}`"
@keyup.enter.native="onEnterPressDown((option as IReagentOption).id)" />
3、通过 document.getElementById 获取到指定元素
4、focus 和 select,聚焦、全选
// 通过元素 id,聚焦到下一行的输入框
const focusNextRowByElementId = (objId: number) => {
// 通过 objId 获取当前行索引
let currentRowIndex = selectedOptionIds.value.indexOf(objId);
// 下一行的输入框
let nextInput: HTMLInputElement;
if (currentRowIndex + 1 < selectedOptionIds.value.length) {
// 下一行索引的 objId
let nextRowObjId = selectedOptionIds.value[currentRowIndex + 1];
nextInput = document.getElementById(`input-apply-amount-${nextRowObjId}`) as HTMLInputElement;
} else {
// 最后一行聚焦到申领用途输入框
nextInput = document.getElementById("transfer-right-footer-purpose-input") as HTMLInputElement;
}
nextInput?.focus();
nextInput?.select();
};
二、通过元素 ref,聚焦到下一行的输入框
关键技术点:
1、动态设置元素 ref 属性为::ref="`input-apply-amount-${(option as IReagentOption).id}`"
2、设置回车监听:@keyup.enter.native="onEnterPressDown((option as IReagentOption).id)"
<el-input
......
:ref="`input-apply-amount-${(option as IReagentOption).id}`"
@keyup.enter.native="onEnterPressDown((option as IReagentOption).id)" />
3、通过 getCurrentInstance() 获取当前组件实例,再通过 refs 获取到元素列表
4、focus 和 select,聚焦、全选
<script setup lang="ts" name="ReagentApplyDialog">
......
import { getCurrentInstance } from "vue";
// 当前组件实例,相当 vue2 的this
const thisInstance = getCurrentInstance();
// 通过元素 ref,聚焦到下一行的输入框
const focusNextRowByElementRef = (objId: number) => {
if (!thisInstance) return;
// 获取输入框实例 Record
let refs = thisInstance.refs as Record<string, HTMLInputElement>;
// 通过 objId 获取当前行索引
let currentRowIndex = selectedOptionIds.value.indexOf(objId);
if (currentRowIndex + 1 < selectedOptionIds.value.length) {
// 下一行索引的 objId
let nextRowObjId = selectedOptionIds.value[currentRowIndex + 1];
// 聚焦到下一行的输入框
refs[`input-apply-amount-${nextRowObjId}`].focus();
refs[`input-apply-amount-${nextRowObjId}`].select();
} else {
// 最后一行聚焦到申领用途输入框
refs["transfer-right-footer-purpose-input"].focus();
refs["transfer-right-footer-purpose-input"].select();
}
};
......
</script>
实例完整代码:
<script setup lang="ts" name="ReagentApplyDialog">
......
import { getCurrentInstance, nextTick, onMounted, ref, watch } from "vue";
// 当前组件实例,相当 vue2 的this
const thisInstance = getCurrentInstance();
// 按回车,申领数量输入框按回车
const onEnterPressDown = (objId: number) => {
// 奇数
if (objId % 2 === 1) {
// 通过元素 id,聚焦到下一行的输入框
focusNextRowByElementId(objId);
}
// 偶数
else {
// 通过元素 ref,聚焦到下一行的输入框
focusNextRowByElementRef(objId);
}
};
// 通过元素 id,聚焦到下一行的输入框
const focusNextRowByElementId = (objId: number) => {
// 通过 objId 获取当前行索引
let currentRowIndex = selectedOptionIds.value.indexOf(objId);
// 下一行的输入框
let nextInput: HTMLInputElement;
if (currentRowIndex + 1 < selectedOptionIds.value.length) {
// 下一行索引的 objId
let nextRowObjId = selectedOptionIds.value[currentRowIndex + 1];
nextInput = document.getElementById(`input-apply-amount-${nextRowObjId}`) as HTMLInputElement;
} else {
// 最后一行聚焦到申领用途输入框
nextInput = document.getElementById("transfer-right-footer-purpose-input") as HTMLInputElement;
}
nextInput?.focus();
nextInput?.select();
};
// 通过元素 ref,聚焦到下一行的输入框
const focusNextRowByElementRef = (objId: number) => {
if (!thisInstance) return;
// 获取输入框实例 Record
let refs = thisInstance.refs as Record<string, HTMLInputElement>;
// 通过 objId 获取当前行索引
let currentRowIndex = selectedOptionIds.value.indexOf(objId);
if (currentRowIndex + 1 < selectedOptionIds.value.length) {
// 下一行索引的 objId
let nextRowObjId = selectedOptionIds.value[currentRowIndex + 1];
// 聚焦到下一行的输入框
refs[`input-apply-amount-${nextRowObjId}`].focus();
refs[`input-apply-amount-${nextRowObjId}`].select();
} else {
// 最后一行聚焦到申领用途输入框
refs["transfer-right-footer-purpose-input"].focus();
refs["transfer-right-footer-purpose-input"].select();
}
};
......
</script>
<template>
......
<el-transfer
......>
<!-- 自定义列表数据项的内容 -->
<template #default="{ option }">
......
<el-input
v-if="selectedOptionIds.includes((option as IReagentOption).id)"
:ref="`input-apply-amount-${(option as IReagentOption).id}`"
:id="`input-apply-amount-${(option as IReagentOption).id}`"
class="input-apply-amount"
style="width: 85px; text-align: center"
v-model="(option as IReagentOption).applyAmount"
placeholder="输入申领数量"
size="small"
clearable
@input="(option as IReagentOption).applyAmount = Number(formatToNumber($event, 0))"
@keyup.enter.native="onEnterPressDown((option as IReagentOption).id)" />
......
</template>
</el-transfer>
......
</template>