Reputation: 1240
I cannot search for child component DOM element, my settings are as follows:
pages/Login.vue
<template>
<section class="login">
<div v-show="step === 4" class="login__container">
<Test />
</div>
</section>
</template>
<script>
export default {
data () {
return {
step: 1
}
},
async mounted () {
this.step = 4
await this.$nextTick()
document.querySelector('.test') // NULL
},
}
</script>
components/Test.vue
<template>
<div class="test">
foo
</div>
</template>
setTimeout of course is not solution. I also try the same on other page, but without success. What am I doing wrong? I guess the problem must be somewhere in the template or project configuration
@edit
i tried to do the same effect on jsfiddle vue template and fresh nuxt project but no problem there
Upvotes: 2
Views: 3114
Reputation: 46696
This kind of code should work properly
parent.vue
<template>
<div>
<test ref="parentTest" @hook:mounted="selectChildElement"></test>
</div>
</template>
<script>
export default {
methods: {
selectChildElement() {
console.log(this.$refs.parentTest.$refs.test)
},
},
}
</script>
Test.vue
component
<template>
<div ref="test">foo</div>
</template>
This is because of the way the parent and children components are mounted, as explained here: https://stackoverflow.com/a/44319825/8816585
As Brahim said, it is also better to use $refs
in an SPA context, more info available here.
The @hook:mounted
trick was taken from this answer and initially found in this dev.to post.
Upvotes: 2
Reputation: 1240
As I thought, the problem is with nuxt, namely auto-importing components. I am using automatic component import in the nuxt configuration.
nuxt.config.js
components: [
{
path: '~/components',
pathPrefix: false,
},
],
This approach apparently breaks something, and only after manually importing the component did it work properly
import Test from '@/components/Test.vue'
export default {
name: 'LoginPage',
components: {
Test
},
So the nuxt configuration caused the problem. Thank you for all your help.
Upvotes: 0
Reputation: 1611
Another way to access child component is emitting event when its ready and created in DOM
,
In the child element:
<template>
<div ref="test">foo</div>
</template>
<script>
export default {
mounted() {
this.$emit('childMounted', this.$refs.test)
}
}
...
In your parent:
<template>
<section class="login">
<div v-show="step === 4" class="login__container">
<Test @childMounted="childMounted"/>
</div>
</section>
</template>
<script>
export default {
data () {
return {
step: 1
}
},
methods: {
childMounted(childRef) {
// Try here
// childRef: your child component reference
}
}
}
</script>
Upvotes: 1
Reputation: 1
You could try to use ref
instead of querySelector
to manipulate the component DOM :
<template>
<section class="login">
<div v-show="step === 4" class="login__container">
<Test ref="test"/>
</div>
</section>
</template>
<script>
export default {
data () {
return {
step: 1
}
},
mounted () {
this.step = 4
let test=this.$refs.test
},
}
</script>
Upvotes: 0