Vue3中如何在v-for中获取触发事件的组件模板Ref引用
解决Vue3中v-for动态组件触发事件时调用自身方法的问题
方案1:让子组件在触发事件时传递自身实例(最优解)
如果可以修改TextInput组件的代码,直接在触发update事件时把组件实例作为参数传递出去,这是最可靠的方式,完全不受v-for顺序变化的影响:
在TextInput组件内部:
// 组件内部触发update事件时,将自身实例作为参数传出 this.$emit('update', this)
父组件中直接接收实例并调用方法:
const callComponentMethod = (componentInstance) => { componentInstance.myCustomMethod() // 直接调用触发事件的组件方法 }
父组件模板:
<TextInput v-for="section in sections" @update="callComponentMethod" />
方案2:用唯一标识映射组件实例(无需修改子组件)
如果无法修改TextInput组件,就用数据源的唯一标识(比如每个section的id)来建立组件实例的映射,避免依赖不可靠的索引:
首先定义一个响应式对象存储组件实例:
const textInputsMap = ref({}) function callComponentMethod(sectionId) { textInputsMap.value[sectionId].myCustomMethod() }
父组件模板中用函数式ref绑定实例,同时传递唯一标识到事件处理函数:
<TextInput v-for="section in sections" :key="section.id" :ref="el => { if (el) textInputsMap.value[section.id] = el }" @update="callComponentMethod(section.id)" />
为什么不用索引?
Vue3文档明确说明,v-for生成的ref数组不保证与源数组顺序一致,尤其是当源数组元素发生增删、排序变化时,ref数组的顺序可能和预期不符,所以通过索引获取组件实例存在风险,上述两种方案都能完美规避这个问题。
内容的提问来源于stack exchange,提问作者Daniel Dilly
相关产品推荐
相关产品推荐

