JAVASCRIPT
Access Child Methods in Vue 3 with `ref` and `defineExpose`
Learn how to call methods of a child component directly from its parent in Vue 3 by using template refs and explicitly exposing methods with `defineExpose`.
<!-- ChildComponent.vue -->
<template>
<div class="child-box">
<p>Child Counter: {{ counter }}</p>
<button @click="increment">Increment from Child</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const counter = ref(0);
const increment = () => {
counter.value++;
console.log('Child incremented!');
};
const reset = () => {
counter.value = 0;
console.log('Child counter reset!');
};
// Expose properties/methods to the parent component
defineExpose({
increment,
reset,
childCounter: counter // Also expose the ref itself if needed
});
</script>
<style scoped>
.child-box {
border: 1px dashed #ccc;
padding: 15px;
margin-top: 20px;
}
</style>
<!-- ParentComponent.vue -->
<template>
<div>
<h1>Parent Component</h1>
<ChildComponent ref="childComponentRef" />
<button @click="callChildIncrement">Call Child Increment</button>
<button @click="callChildReset">Call Child Reset</button>
<p v-if="childComponentRef && childComponentRef.childCounter">
Child's Counter (via ref): {{ childComponentRef.childCounter }}
</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// Create a ref to hold the child component instance
const childComponentRef = ref(null);
const callChildIncrement = () => {
if (childComponentRef.value) {
childComponentRef.value.increment();
}
};
const callChildReset = () => {
if (childComponentRef.value) {
childComponentRef.value.reset();
}
};
</script>
How it works: While passing props down and emitting events up is the primary way to communicate between parent and child components in Vue, there are cases where a parent needs to directly invoke a method on a child. In Vue 3's Composition API with `<script setup>`, you use `ref` to get a reference to the child component in the template. Within the child component, `defineExpose` explicitly declares which properties or methods should be accessible through this `ref`. This ensures a clear contract and avoids implicitly exposing all internal component state.