Hi Vue developer! Surely you’ve already used lifecycle hooks in Vue in order to perform different actions when the component is created, mounted or destroyed. You’ve also probably used custom events for communication between a component and its parent.
But… did you know that Vue’s lifecycle hooks emit their own custom events? Yeah, that’s something Damian Dulisz showed with this tweet and it was enlightening.
You might be thinking… Why should I care, Alex? Well, it’s a good to know trick that can be useful in some cases. I’m going to show you a couple of them in this article.
Listening to Children Hooks
Vue’s lifecycle hooks emit custom events with the name of the hook itself, prefixed by hook:
. For example, the mounted
hook will emit a hook:mounted
event.
You can therefore listen to children hooks from the parent components, just as you would do with any custom event:
<template> <Child @hook:mounted="childMounted"/> </template> <script> import Child from "./Child"; export default { components: { Child }, methods: { childMounted() { console.log("Child was mounted"); } } }; </script>
That can be useful as well to react to third-party plugins hooks. For instance, if you want to perform an action when v-runtime-template finishes rendering the template, you could use the @hook:updated
event:
<template> <v-runtime-template @hook:updated="doSomething" :template="template"/> </template>
Seems like magic, ha? Probably you’ve already come across these cases and you created a hook on the child just to let the parent know that the hook was called. Well now know it’s not necessary!
If you don’t trust me, you’ll find a demo by the end of the article 😛.
Registering Hooks Dynamically
Although uncommon, there could be some occasions when you’d need to register a hook dynamically the same way you can create custom events dynamically. You can do that by using the $on
, $once
and $off
hooks.
Take the following example, taken from Damian’s tweet, creating a beforeDestroy
hook dynamically due to the fact that is creating a wrapper Vue component for Pickaday: a plain JavaScript date-picker library.
Since the plugin must be created on the mounted hook and it’s not saving the instance in a reactive state variable, the only way to do something with it is by registering the beforeDestroyed
hook right after creating the Pickaday instance:
export default { mounted() { const picker = new Pickaday({ // ... }); this.$once("hook:beforeDestroy", () => { picker.destroy(); }) } };
Wrapping Up
You’ve seen the trick of using the hook:
events to react to the hook calls without the need to emit any event manually. I hope this was a hot trick for you! 🔥
You can see the code and a demo of this article in this Codesandbox.
Stay cool 🦄