Calling methods (functions) outside a Vue Component used to feel a little hacky. With Vue 3 and the Composition API, we can easily expose methods and make them available to parent components.
Take this simple component that invokes a method when a button is clicked:
<script setup>
const doSomething = () => {
console.log('i did something')
}
</script>
<template>
<button v-on:click="doSomething">Do something</button>
</template>
In our main App
component, we'll import and add it to the page.
<script setup>
import ChildComponent from './components/ChildComponent.vue'
</script>
<template>
<ChildComponent />
</template>
Pretty simple so far. Let's get started with exposing this method.
The first change we'll make is to use defineExpose
to provide an object of methods we want to expose from this component:
<script setup>
const doSomething = () => {
console.log('i did something')
}
defineExpose({
doSomething
})
</script>
This will allow us to access this method once we have a reference to the child component.
Now we've exposed a method, it's time to reference the child component. Here's the complete code, where we:
ref
which holds a reference to the child componentdoSomething
method on the ref<script setup>
import ChildComponent from './components/ChildComponent.vue'
import { ref } from 'vue'
const childComponent = ref(null)
</script>
<template>
<ChildComponent ref="childComponent" />
<button v-on:click="childComponent.doSomething()">
Call child component method
</button>
</template>
Hitting that button will invoke the method we've exposed from the ChildComponent
component.
If you need to expose a method that belongs to a third-party dependency or one that exists within an object, you'll need to slightly change how you define your exposed methods. Here's an example:
<script setup>
const someObject = {
someObjectMethod: () => {
console.log('called someObjectMethod')
}
}
defineExpose({
someObjectMethod: () => {
someObject.someObjectMethod()
}
})
</script>
We wrap the underlying call to the method within someObject
in another method so we can invoke it.
So, exposing methods using Vue 3 and the Composition API is relatively easy. I recommend using this pattern sparingly, or you risk having too many dependencies between your components. If things get more complicated, reach for a state management library like Pinia or use basic state management with composables.