can’t use template ref on component in vue 3 composition api

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.

Leave a Comment

tech