Using DefineExpose In Vue

March 29, 2022

When you have a component using script tags containing setup, the component's bindings will not be reached by the parent component. If you want to share info with a parent component, you can use defineExpose to expose only the values you supply in its parameters. This is useful when you need to access a function or a single element in the child component.

In this example, the child component has a function showAlert that will display an alert window. In order for a parent component to use this funciton, you need to pass showAlert in a defineExpose to make it accessible. defineExpose does not need to be imported.

// child component

<script setup>

function showAlert() {
  alert('hello')
}

defineExpose(({
  showAlert
}))
</script>

<template>
  <div class="greetings">
  </div>
</template>

For the parent component to use this function, there needs to be a ref on that child component. I created a ref called HelloWorldRef and assigned it to the child component. With this ref I can now call the function by assigning a button's click event to HelloWorldRef?.showAlert(). The ref created needs to be called first to access the exposed function.

// parent component

<script setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue'

const HelloWorldRef = ref()
</script>

<template>
  <header>
    <div class="wrapper">
      <HelloWorld ref="HelloWorldRef"/>
    </div>
    <button @click="HelloWorldRef?.showAlert()">Say Hello</button>
  </header>
</template>

I first learned of defineExpose when I was considering accessibility. The problem was that I needed to access a child component's elements to fire a focus() on a particular one if the user pressed the tab key.

Following the same process as the example above, I included a ref on a child component's element and referenced it in the parent component like this: HelloWorldRef?.childElementRef?.$el.focus().

Resources