DEV Community

Discussion on: Vue.js - How I call a method in a component from outside the component in Vue 2

koas profile image

Thans for the article! I'd like to share how I implement component communication in my apps, since it's vanilla JS and thus framework agnostic it may give another point of view.

I currently use Vue for my apps, but before that I used plain JS and then jQuery and sometimes I needed a way to notify my components of some events. When learning the Windows API back on my days I learned about the event message system and thought that philosophy would work well for my JS needs.

The basic idea is use JavaScript's dispatchEvent to emit a CustomEvent message. Any other component in my app could listen to those message and take action.

So let's say we have a data table component that lists our app's sales, and we want to update the table in real time whenever a sale is completed. To achieve this our API should notify the web app of the sale using Pusher or any other web socket solution, and when we receive that notification we emit the message event. I've chosen WM_MESSAGE for the event name as a wink to the good old Windows API, where all messages begin with WM_.

// A sale has been made, emit the message. orderId and amount are provided by the API.
const detail = {msgId: "NEW_SALE", orderId, amount};
const evt = new CustomEvent("WM_MESSAGE", {detail});
Enter fullscreen mode Exit fullscreen mode

In our data table component we would then listen to the WM_MESSAGE event and take action if the message id is NEW_SALE:

window.addEventListener("WM_MESSAGE", messageHandler);

function messageHandler(e)
  if (e.detail.msgId == "NEW_SALE")
    // Here we would call our component's update data method
Enter fullscreen mode Exit fullscreen mode

You can emit as many WM_MESSAGE events as you need with different msgId properties to notify your app components of any local or remote event.

What I like most about this method is that is just plain JS! When I switched from jQuery to Vue I had to rewrite my components but didn't have to change this code, since it didn't depend on any jQuery feature. And since it doesn't use any Vue features no change will be required when I upgrade to Vue 3 or change to another framework in the future.