当前位置: 首页 > news >正文

Vue3 + TypeScript + Element Plus + el-input 输入框列表按回车聚焦到下一行

应用效果:从第一行输入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) {// 下一行索引的 objIdlet 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;// 获取输入框实例 Recordlet refs = thisInstance.refs as Record<string, HTMLInputElement>;// 通过 objId 获取当前行索引let currentRowIndex = selectedOptionIds.value.indexOf(objId);if (currentRowIndex + 1 < selectedOptionIds.value.length) {// 下一行索引的 objIdlet 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) {// 下一行索引的 objIdlet 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;// 获取输入框实例 Recordlet refs = thisInstance.refs as Record<string, HTMLInputElement>;// 通过 objId 获取当前行索引let currentRowIndex = selectedOptionIds.value.indexOf(objId);if (currentRowIndex + 1 < selectedOptionIds.value.length) {// 下一行索引的 objIdlet 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-inputv-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>

相关文章:

  • 【微信小程序】4、SpringBoot整合WxJava生成小程序码
  • CDN加速导致CLS升高图片托管服务器的3个选择标准!
  • 解密 Spring MVC:从 Tomcat 到 Controller 的一次完整请求之旅
  • Java求职者面试:Spring AI、MCP、RAG、向量数据库与Embedding模型技术解析
  • 世事无两全
  • 串口DMA + 环形缓冲,共用缓冲区
  • 使用Trace分析Android方法用时
  • Pyenv 跟 Conda 还有 Poetry 有什么区别?各有什么不同?
  • 在使用 HTML5 的 <video> 标签嵌入视频时,有时会遇到无法播放 MP4 文件的问题
  • python打卡day54@浙大疏锦行
  • 黑马教程强化day5-2
  • 【Node.js 的底层实现机制】从事件驱动到异步 I/O
  • 什么是Flink
  • 红队攻防渗透技术实战流程:信息打点-主机架构蜜罐识别WAF识别端口扫描协议识别服务安全
  • Uniapp H5端SEO优化全攻略:提升搜索引擎排名与流量
  • JVM 内存模型与垃圾回收机制全解析:架构、算法、调优实践
  • Minio 基于 bearer_token 监控
  • 【AI作画】用comfy ui生成漫画风图画
  • python调用 powershell 执行dir 并获取每行的length列属性值
  • 【数据分析九:Association Rule】关联分析
  • 广州注册公司地址要求/seo技巧seo排名优化
  • ui培训排名/关键词在线优化
  • 天津做网站印标/杭州推广系统
  • 网站建设入驻/网站关键词排名服务
  • 个人网站模板/汕头网站建设方案开发
  • 集团网站建设服务平台/快速排名官网