v-for循环渲染的子组件中v-form的ref失效,如何解决?
问题:Vuetify v-for渲染的子组件中v-form的ref无法获取
父组件通过v-for循环渲染多个子组件,每个子组件内包含v-form,点击下一步按钮时需要校验当前显示的子组件表单,但子组件内v-form的ref始终未定义,仅v-window-item的ref能正常读取。
父组件代码(parent.vue)
<template> <v-card> <v-window v-model="currentStep" touchless> <child-component v-for="page in pages" ref="criteriaData" :key="page"/> </v-window> <v-btn @click="nextPage">NEXT</v-btn> </v-card> </template> <script> export default { name: 'Parent', components: { ChildComponent }, data() { return { currentStep: 0, pages: [0, 1] } }, methods: { nextPage() { if (this.$refs.criteriaData[this.currentStep].validateComponent()) { this.currentStep++ // do something else } } } } </script>
子组件代码
<template> <v-window-item ref="outerRef"> <v-form ref="criteriaForm" v-model="valid"> <v-text-field v-model="value" :rules="required" /> </v-form> </v-window-item> </template> <script> export default { name: 'childComponent', data() { return { required: [ v => !!v || 'Required!' ], valid: null, value: 0 } }, mounted() { console.log('mounted') console.log(this.$refs) }, methods: { validateComponent() { console.log('ValidateComponent gets properly called') return this.$refs.criteriaForm.validate() }, } } </script>
控制台输出
mounted Object{ outerRef: {...} } ValidateComponent gets properly called [Vue warn]: Error in v-on handler: "TypeError: can't access property "validate", this.$refs.criteriaForm is undefined"
原因分析
Vuetify的v-window组件默认开启懒加载,仅当前激活的标签页对应的内容会被实际渲染到DOM中。未激活的子组件里,v-window-item作为容器会被渲染,但内部的v-form及表单元素不会被挂载,因此$refs.criteriaForm自然无法获取到。
解决方案
给v-window添加lazy="false"属性,关闭懒加载行为,这样所有子组件的内容会在初始化时全部渲染,v-form的ref就能正常被读取:
<v-window v-model="currentStep" touchless lazy="false"> <child-component v-for="page in pages" ref="criteriaData" :key="page"/> </v-window>
如果不想关闭全局懒加载,也可以针对性地确保仅校验当前激活的子组件,利用v-window的激活状态判断,但关闭懒加载是最直接的解决方式,尤其适合表单数量不多的场景。
内容的提问来源于stack exchange,提问作者Moritz M.
相关产品推荐
相关产品推荐

