15

I am trying to access a ref in a child component using the Vue3 composition API, but i am unsure of how to do so. I would like to add a scroll event to the mainContentRef so i can do a fetch request to grab more data within the parent component but i can't seem to access the ref in the parent component to add the event listener to it

This is my code (some parts removed due to being unnecessary for this example):

<!-- MAIN COMPONENT -->
<template>
    <PageWrap>
        <template v-slot:content>
            <MainContent>
                <template v-slot:content />
            </MainContent>
        </template>
    </PageWrap>
</template>

<script setup>

//access mainContentRef here because this is where the fetch request will be

</script>


<!-- MAIN CONTENT COMPONENT -->
<template>
    <div id="main-content" ref='mainContentRef'>
        <slot name='content'></slot>
    </div>
</template>

<script setup>

    import { defineProps, ref } from 'vue';

    const mainContentRef = ref(0);

</script>

2 Answers 2

27

You could utilize vue's defineExpose method and then add a ref for your MainContent component and access it through that.

<!-- MAIN COMPONENT -->
<template>
    <PageWrap>
        <template v-slot:content>
            <MainContent ref="mainContentComponent">
                <template v-slot:content />
            </MainContent>
        </template>
    </PageWrap>
</template>

<script setup>
    const mainContentComponent = ref()
    
    // Now you can do:
    mainContentComponent.value.mainContentRef.value
</script>


<!-- MAIN CONTENT COMPONENT -->
<template>
    <div id="main-content" ref="mainContentRef">
        <slot name='content'></slot>
    </div>
</template>

<script setup>
    import { ref } from 'vue'
    
    const mainContentRef = ref(0)
    
    defineExpose({
        mainContentRef
    })
</script>

See Also: https://vuejs.org/guide/essentials/template-refs.html#ref-on-component

Let me know if you have any questions or it doesn't work, happy to help!

Sign up to request clarification or add additional context in comments.

4 Comments

Oh wow, i didn't know you could do that! I'll try the defineExpose method as i've not come across this! I'll try and implement it and see how it goes! Thank you for your help!
Using define exposed within the main content component and using a ref on the child component worked wonders! I have successfully logged out the div which will (hopefully) now allow me to attach my event listener onto it! Thank you!
you're using defineExpose but importing defineProps, is it intentional or mistake?
mainContentComponent.value.mainContentRef.value ... this is not cool.
1

you can try:

<!-- MAIN CONTENT COMPONENT -->
<template>
    <div id="main-content" ref='mainContentRef'>
        <slot name='content'></slot>
    </div>
</template>

<script setup>

    import { defineProps, ref } from 'vue';

    const mainContentRef = ref(null);

     // Now you can do:
     mainContentRef.value.children[0]

</script>

3 Comments

How is this any better then the accepted answer that actually using a child component.
@Whitespacecode it took me time to read and understand the difference after I saw your comment. and now I just realized that it's a cool trick.
@Hayyaun there are better ways, i just used OP question to build the answer that works on his example. You should just use defineExpose in the child component to have access to child component stuff

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.