Trigger a unique event using Vanilla JS and then detect it on Vue instances

I am currently in the process of incorporating multiple Vue instances into my website. I have encountered issues preventing me from making the entire website a Vue instance and using components due to potential conflicts and other complications.

For example, consider the following:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
  </head>
  <body>
    <div id="vueOne"></div>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae sem eget tortor accumsan pellentesque ac commodo quam. Fusce efficitur, nisl non vehicula venenatis, libero augue efficitur nisi, non mollis nulla enim nec dolor. Curabitur leo diam, aliquam ac nisl in, cursus eleifend elit. Praesent euismod dapibus nisi ac semper. Donec massa lectus, vestibulum ut tristique eget, mollis eu nunc. Morbi dignissim lacinia pharetra. Maecenas consectetur libero sed risus cursus mattis</p>
    <div id="vueTwo"></div>
    <script>
        new Vue({
            el: '#vueOne',
            data: {
                count: 0
            }
        });
        new Vue({
            el: '#vueTwo',
            data: {
                count: 0
            }
        });

    </script>
  </body>
</html>

Is there a method to trigger a custom event in Vanilla JS and have the Vue instances recognize it?

Answer №1

When setting up events on your Vue elements or components, the event listeners used are similar to those set up on regular HTML elements. This means that you can obtain a reference to the element where the event listener is attached and trigger a custom event using dispatchEvent.

For example, if you have an event named my-event set up on a div like this:

<div id="vueOne" v-on:my-event="myListener">{{count}}</div>

You can use querySelector("#vueOne") to access that specific element and then call dispatchEvent() on it

document.querySelector("#vueOne").dispatchEvent( new CustomEvent("my-event") );

Demo

new Vue({
  el: '#vueOne',
  data: {
    count: 0
  },
  methods:{
    myListener:function(){
      this.count++;
      console.log("listener called");
    }
  }
});
new Vue({
  el: '#vueTwo',
  data: {
    count: 0
  }
});

setTimeout(function(){
  document.querySelector("#vueOne").dispatchEvent( new CustomEvent("my-event") );
},2000);
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="vueOne" v-on:my-event="myListener">{{count}}</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vitae sem eget tortor accumsan pellentesque ac commodo quam. Fusce efficitur, nisl non vehicula venenatis, libero augue efficitur nisi, non mollis nulla enim nec dolor. Curabitur leo diam, aliquam
  ac nisl in, cursus eleifend elit. Praesent euismod dapibus nisi ac semper. Donec massa lectus, vestibulum ut tristique eget, mollis eu nunc. Morbi dignissim lacinia pharetra. Maecenas consectetur libero sed risus cursus mattis</p>
<div id="vueTwo"></div>

Answer №2

I implement a similar approach by creating a separate Vue instance dedicated to messaging functions only. This allows me to trigger events from non-Vue components and utilize them within Vue, as well as vice versa.

window.Event = new class {
  constructor() {
    this.vue = new Vue();
  }
  fire(event, data = null) {
    this.vue.$emit(event, data);
  }
  listen(event, callback) {
    this.vue.$on(event, callback);
  }
}

Within a component, I set up an event listener:

created () {
    Event.listen('notification', function (msg) {
      console.log(msg);
    });
  }

This enables me to send messages like so:

Event.fire('notification', {
    title: 'Hello from notification through message :)';
});

Because the event class is attached to the window object, it remains accessible across all components and functions. This provides a simple way to facilitate communication between different Vue instances, Vue to vanilla JS, and vice versa.

Furthermore, since the Vue instance is specialized for messaging purposes only, the overhead is minimal. Multiple event listeners can be added, accommodating various types of messages directed at different recipients or setting up multiple handlers for the same message.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an unexpected token ';' in a random generator while attempting to utilize an if-else statement for determining DOM manipulation

After dabbling in programming on and off for a few years, I've finally decided to dive deep with some simple personal projects. One of the tasks I'm working on is creating a randomizer for a pen and paper RPG, where it samples from an array at ra ...

"By selecting the image, you can initiate the submission of the form

I am trying to figure out why clicking on the image in my form is triggering the form submission by default. Can someone please provide guidance on this issue? <form name="test1" action="er" method="post" onsubmit="return validateForm()" <input ty ...

unusual behavior of UTF-8 characters in Blogger when utilizing JavaScript

I'm facing a peculiar issue with JavaScript in my Blogger code when dealing with certain characters like '¡' and '?'. For instance, the following code snippet displays ñéúüëò¡!¿? inside the div but shows ñéúüëò&# ...

How come my total isn't zero after I get a 1 on the dice roll?

I've been working on a dice game where if either of the dice rolls a 1, the score is set to 1. However, I'm having trouble getting that part of my code to work properly. I'm confident that everything else is functioning correctly. v ...

Error: The function initMap() is not recognized in the Google Maps API

I have been experimenting with the Flickr API and I'm currently working on asynchronously loading images along with their metadata. To accomplish this, I have a script that utilizes three AJAX calls: $(document).ready(function() { var latLon = { ...

Vessel situated after the helm

There seems to be an issue with my toolbar and sidenav overlapping the contents of my container. I thought about adding a top margin to the container to fix the problem caused by the toolbar, but adjusting the sidenav in the same way creates display probl ...

A ReactJS Error occurred: {error: 400, reason: "Failed match", message: "Failed match [400]", errorType: "Meteor.Error"}

I encountered an issue while attempting to send form data to the server when clicking on the Next Button in a Wizard Form. The error that occurs is related to an "Undefined User" warning displayed in the Console during Step 1 of the form submission: " { ...

Unable to retrieve basic profile data from LinkedIn Members using their email ID unless they are signed in

I am struggling to retrieve the basic profile details of Linkedin Members using their email ID. Despite my efforts, I haven't been able to find relevant information in the documentation. My attempt involved creating an app, initializing the JavaScrip ...

Stop the reoccurring action for a jQuery plugin by using the clearInterval function

Having a difficulty with clearing the interval inside a jQuery plugin. Below is a simplified code snippet. When attempting to run the following in the Firefox console: $('.banner').pluginName().stop() the console keeps logging `console.log(1)`. ...

Create geometric shapes on Google Maps version 2

Can anyone guide me on how to draw a polygon on Google Maps with user-input coordinates? I have two input fields for latitude and longitude, and when the user clicks the button, I want the polygon to be drawn. The code I currently have doesn't seem to ...

Dealing with prompt boxes in Robot Framework: A Guide

Currently, I am utilizing the Robot Framework in conjunction with Selenium2Library for automating tests on websites. During one particular scenario, a prompt box appeared (similar to an alert but containing an input field). The challenge is that Robot Fram ...

Variations between <div/> and <div></div>

When using Ajax to load two divs, I discovered an interesting difference in the way they are written. If I write them like this: <div id="informCandidacyId"/> <div id="idDivFiles"/> Although both divs are being loaded, only one view is added ...

Unable to fetch a new session from the selenium server due to an error

I'm currently in the process of setting up Nightwatch.js for the very first time. I am following the tutorial provided at this link: https://github.com/dwyl/learn-nightwatch Unfortunately, I have encountered a barrier and require assistance to resolv ...

Proceed with downloading the file only when a checkbox has been ticked off and the form has been

Is there a way to make a PDF download only when a user checks a checkbox and submits the form, rather than just checking the checkbox and hitting submit? I am limited to using Jquery or plain javascript and do not have access to backend files. The checkbox ...

Converting a UUID from a string to an integer in JavaScript

Need help passing a UUID to a function that calls an endpoint to delete a blog. The UUID is in string format like "9ba354d1-2d4c-4265-aee1-54877f22312e" and I'm encountering a TypeError: Cannot create property 'message' on string '9ba35 ...

What is the best way to remove extra information from a redirect URL?

Implementing Discord login OAuth2 in JavaScript has been quite a journey. I have managed to redirect to '/auth' upon completion, but the URL for that page comes with additional information like '/auth#token_type=Bearer&access_token=12eka ...

Choose a particular text node from the element that has been selected

Can anyone provide guidance on how to extract the text "Items Description" from the following HTML snippet using jQuery? <div class="items"> "Items Description" <ul> <li>1. One</li> <li>2. Two</li&g ...

broker handling numerous ajax requests simultaneously

Is there a way to efficiently handle multiple simultaneous ajax calls and trigger a callback only after all of them have completed? Are there any JavaScript libraries available that can manage numerous ajax calls to a database at the same time and execute ...

The template for a Vue dynamic component refuses to function properly with a promise

<template> <component :is="myComponent" /> </template> <script> export default { props: { component: String, }, data() { return { myComponent: '', }; }, computed: { loader() { ...

Activate Bootstrap datetimepicker by using the enter key to automatically populate the initial date

Check out the Bootstrap datetimepicker on this page: I'm trying to make it so that when the datetimepicker is first shown, pressing the enter key will hide the widget and insert the current date into the input field. I've experimented with a few ...