Vue cookbook · Beginner

Access child component methods with template refs and defineExpose

A parent needs to focus an input or reset a form inside a child component.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Expose a small, explicit API from the child with defineExpose, and reference it in the parent with useTemplateRef, typed with InstanceType<typeof Child>.

Solution

<!-- SearchBox.vue -->
<script setup lang="ts">
import { ref, useTemplateRef } from "vue";

const query = ref("");
const input = useTemplateRef<HTMLInputElement>("input");

defineExpose({
  focus: () => input.value?.focus(),
  clear: () => (query.value = ""),
});
</script>

<template>
  <input ref="input" v-model="query" type="search" />
</template>
<!-- Toolbar.vue -->
<script setup lang="ts">
import { useTemplateRef } from "vue";
import SearchBox from "./SearchBox.vue";

const search = useTemplateRef<InstanceType<typeof SearchBox>>("search");
</script>

<template>
  <SearchBox ref="search" />
  <button @click="search?.focus()">Search (/)</button>
  <button @click="search?.clear()">Clear</button>
</template>

Pitfalls

  • Reaching into a child's internal state; <script setup> components are closed by default for good reason.
  • Using refs to pass data down that should be props.
  • Accessing refs before mount (they're null until then).

Variations

  • For many imperative needs (focus on mount), a v-focus custom directive is simpler.
  • Use the ComponentExposed type from vue-component-type-helpers for generic components.

Further reading: Template refs

Reference: https://vuejs.org/guide/essentials/template-refs.html

More Vue recipes

Was this page helpful?