Vue中如何通过refs给v-for动态生成的input设置自动聚焦
动态ref绑定后input元素聚焦失效解决方案
失效原因
- Vue的DOM更新是异步批量执行的,新增列表项后同步访问
$refs时,新的input元素还未完成挂载,$refs还没更新对应节点,因此取不到目标元素。 - 不同版本Vue的
$refs在v-for场景下的结构有差异,Vue3中v-for内绑定的动态ref默认会被包裹为数组,直接访问得到的是数组而非DOM元素,调用focus方法自然无效。
方案1:结合$nextTick适配$refs结构
新增元素后等待DOM更新完成再执行聚焦操作,同时根据Vue版本调整$refs取值逻辑:
模板代码(保持原有写法即可)
<input v-for="(item, index) in list" :key="index" :ref="`input-${index}`" v-model="item.value" >
新增逻辑代码
// 新增列表项方法 addInputItem() { // 向列表插入新项 this.list.push({ content: '' }) const lastIndex = this.list.length - 1 // 等待DOM异步更新完成 this.$nextTick(() => { let targetInput // Vue2环境直接取值 if (Vue.version.startsWith('2.')) { targetInput = this.$refs[`input-${lastIndex}`] // Vue3环境取数组第一个元素 } else { targetInput = this.$refs[`input-${lastIndex}`]?.[0] } // 安全调用focus方法 targetInput?.focus() }) }
方案2:使用函数式ref(更稳定,无版本兼容问题)
直接通过函数式ref把input实例收集到自己维护的数组中,完全规避$refs的结构不确定性:
模板代码修改为
<input v-for="(item, index) in list" :key="index" :ref="el => { if (el) this.inputRefs[index] = el }" v-model="item.value" >
业务代码调整
// data中初始化存储ref的数组 data() { return { list: [], inputRefs: [] } }, methods: { addInputItem() { this.list.push({ content: '' }) const lastIndex = this.list.length - 1 this.$nextTick(() => { this.inputRefs[lastIndex]?.focus() }) } }
如果你绑定ref的是封装的自定义输入组件而非原生input元素,需要确保组件内部对外暴露了focus方法,或者通过
$el访问原生DOM再调用focus:targetInput.$el?.focus()
内容的提问来源于stack exchange,提问作者yourivdloo
相关产品推荐
相关产品推荐

