Parent Component:
...
<v-stepper-step
:rules="[()=>isValid(1)]"
>
MyStep
</v-stepper-step>
<v-stepper-content>
<Mytag ref="MyReference" />
</v-stepper-content>
...
methods: {
isValid(number){
return mySwitch(number)
}
mySwitch(number){
let v = false
switch(number){
case '1':
v = this.$refs.MyReference.$refs.MyTagForm.validate()
break
}
return v
}
}
Child Component:
...
<v-form
ref="MyTagForm"
>
...
</v-form>
...
Following problem: as soon as the page is loaded I get the TypeError: Cannot read properties of undefined (reading '$refs'). BUT as soon as the page is loaded and I change between steps everything with the validation is fine.
I think the problem is that the reference just doesn't exist at the very beginning. I tried to use setInterval and setTimeout around the method in isValid and in mySwitch - but then the validation is always false.
I hope someone of you can help.
Parent Component:
...
<v-stepper-step
:rules="[()=>isValid(1)]"
>
MyStep
</v-stepper-step>
<v-stepper-content>
<Mytag ref="MyReference" />
</v-stepper-content>
...
methods: {
isValid(number){
return mySwitch(number)
}
mySwitch(number){
let v = false
switch(number){
case '1':
v = this.$refs.MyReference.$refs.MyTagForm.validate()
break
}
return v
}
}
Child Component:
...
<v-form
ref="MyTagForm"
>
...
</v-form>
...
Following problem: as soon as the page is loaded I get the TypeError: Cannot read properties of undefined (reading '$refs'). BUT as soon as the page is loaded and I change between steps everything with the validation is fine.
I think the problem is that the reference just doesn't exist at the very beginning. I tried to use setInterval and setTimeout around the method in isValid and in mySwitch - but then the validation is always false.
I hope someone of you can help.
Share Improve this question asked Dec 29, 2021 at 11:06 user17788162user17788162 2-
:rules="()=>isValid(1)]"
is this line correct, plz check the]
. – Dark Knight Commented Dec 29, 2021 at 11:07 - @DarkKnight thanks, I updated the code in the mwe – user17788162 Commented Dec 29, 2021 at 11:12
1 Answer
Reset to default 1The problem is that in Vue.js, a ponent is rendered through a particular set of stages--for instance, a ponent is first created before it is mounted--and you're attempting to retrieve a reference to a rendered DOM object that has not yet been rendered by the framework. In other words, you're trying to retrieve something that doesn't yet exist (as you suspected).
In order to resolve this problem, you have to account for the child ponent not yet being rendered, choosing instead to defer validation until the ponent has been mounted. One such option would be to have the child ponent signal to the parent when it has successfully mounted and return a default validation value of true
or false
until then. This example should illustrate the idea:
...
<v-stepper-step
:rules="[()=>isValid(1)]"
>
MyStep
</v-stepper-step>
<v-stepper-content>
<Mytag ref="MyReference" v-on:ready="childReady = true" />
</v-stepper-content>
{
...
data() {
return {
childReady: false
}
},
methods: {
isValid(number){
return mySwitch(number)
}
mySwitch(number){
// Prevents the normal switch code from running until the child ponent mounts.
if(!this.childReady) {
return false;
}
let v = false
switch(number){
case '1':
v = this.$refs.MyReference.$refs.MyTagForm.validate()
break
}
return v
}
}
...
<v-form
ref="MyTagForm"
>
...
</v-form>
...
{
...
mounted() {
// The mounted lifecycle hook will signal the "ready" event when this ponent is rendered, allowing the parent to know that this ponent has finished rendering.
this.$emit('ready');
}
}
There are, of course, other ways that you can manage this, and I would argue that there are multiple much better solutions than the one I've illustrated above. That said, I wanted to keep this answer simple; the above should hopefully be sufficient for aiding you in grasping what the underlying problem is and giving you the starting point for better designing the solution you want in your code.