I ran into this issue today. The problem is that, when using the <script setup>
pattern, none of the declared variables are returned. When you get a ref to the component, it’s just an empty object. The way to get around this is by using defineExpose
in the setup block.
// Child.vue
<template>
<div ref="wrapper">
<!-- content ... -->
</div>
</template>
<script setup>
import { defineExpose, ref } from 'vue'
const wrapper = ref(null)
defineExpose({ wrapper })
</script>
The way you set up the template ref in the parent is fine. The fact that you were seeing empty object { }
in the console means that it was working.
Like the other answer already said, the child ref can be accessed from the parent like this: wrapper.value.wrapper.getBoundingClientRect()
.
The rfc has a section talking about how/why this works: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0040-script-setup.md#exposing-components-public-interface
It’s also important to note that, with the <script setup>
pattern, your ref in the parent component will not be a ComponentInstance. This means that you can’t call $el
on it like you might otherwise. It will only contain the values you put in your defineExpose
.