Enabling communication between two single file components

Is there a way for two single file components to communicate with each other?

Consider this scenario: I have two components, Content.vue and Aside.vue

I want to be able to trigger an update in the Content.vue component when a button inside Aside.vue is clicked.

This is how the two single file compontents are structured inside the index.html:

  <div class="container articleContainer">
    <article-content></article-content>
    <article-aside></article-aside>
  </div>

Aside.vue:

<template>
  <aside>
    <span @click="updateCounter">This is an aside.</span>
  </aside>
</template>

<script>
  export default {
    data() {
      return {
        aside: "aside message"
      }
    }
  }
</script>

Content.vue

<template>
  <article>
    <p>{{ counter }}</p>
    <button @click="updateCounter">Update Counter</button>
  </article>
</template>

<script>    
  export default {
    data() {
      return {
        counter: 0
      }
    },
    methods: {
      updateCounter: function() {
        this.counter = this.counter + 2;
      },
    }
  }
</script>

If a user clicks on the span element inside the Aside template, how can we leverage the updateCounter method to modify the counter value within Content.vue?

Answer №1

If your application isn't large or complex enough to warrant using Vuex, you can create an EventBus like the following:

export const EventBus = new Vue();// Define in your main.js file

In Aside.vue:

<template>
  <aside>
    <span @click="updateCounter">This is an aside.</span>
  </aside>
</template>

<script>
import {EventBus} from './path/to/main.js'
  export default {
    data() {
      return {
        aside: "aside message"
      }
    },
    methods:{
        updateCounter(){
            EventBus.emit('updateCounter');
        }
    }
  }
</script> 

In Content.vue

<template>
  <article>
    <p>{{ counter }}</p>
    <button @click="updateCounter">Update Counter</button>
  </article>
</template>

<script>  
  import {EventBus} from './path/to/main.js'
  export default {
    data() {
      return {
        counter: 0
      }
    }
    created() {
        
        EventBus.on('updateCounter', () => {
            this.counter = this.counter + 2;
        });
    },
    methods: {
        updateCounter: function() {
            this.counter = this.counter + 2;
        },
    }
  }
</script> 

Answer №2

One way to approach this issue is by setting a value in the App.vue that can be accessed by both components. This involves using the

this.$parent.someParentMethod(someValue);
method along with passing data through props.

Alternatively, a more streamlined and recommended solution is to utilize Vuex.

Answer №3

Enhancing Component Communication with Event Bus in Vue.js

Event Bus in Vue.js opens up communication channels between components beyond typical parent-child relationships.

<script>
export default
    name: 'ComponentA',
    methods: {
        sendGlobalMessage() {
            this.$root.$emit('message_from_a', arg1, arg2);
        }
    }
}
</script>

In the example above, ComponentA triggers an event named "message_from_a" and includes optional arguments. Any other component can listen for and respond to this event.

<script>
export default
    name: 'ComponentB',
    mounted() {
        this.$root.$on('message_from_a', (arg1, arg2) => {
            console.log('Message received');
        });
    }
}
</script>

To listen for events in ComponentB, we need to register the event first. This can be done by adding an event listener within the mounted() lifecycle hook. The callback function inside mounted() will be executed whenever an event is emitted from any component.

source

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

How can I restrict the selection of only one checkbox within an iframe window?

Here is my JavaScript snippet: var iframe = document.getElementById('pltc'); iframe.contentWindow.document.open('text/htmlreplace'); iframe.contentWindow.document.write('<input type="checkbox" name="tc0">Yes<input type="c ...

Having trouble retrieving a Vue component from a JSP page

I am currently facing a challenge in implementing a Vue component within my JSP page. I have attempted to access a JavaScript file that contains import and export statements by using the type="module" attribute in the script tag. The file was successfully ...

Exchanging data between dynamic child components

As a newcomer to vuejs, I've encountered an issue with my parent component and its child components. The children swap in and out using <component :is="view">, where the view is a property of the parent component. Each child component needs to b ...

It is essential for each child in a list to be assigned a unique "key" prop to ensure proper rendering, even after the key has been assigned (in Next

Working with Next JS and implementing a sidebar with custom accordions (created as SideAccord.js component). Data is being looped through an array with assigned keys, but still encountering the following error: Warning: Each child in a list should have a u ...

Having trouble importing from the src folder in Expo React

I am currently using expo-cli. When I import a module from the 'src' folder (which I created), it works perfectly fine when opened in a web browser, but encounters an error when opened on an Android device. I have tried using absolute paths and ...

Creating a selection area with CSS that appears transparent is a straightforward process

I'm currently exploring ways to implement a UI effect on a webpage that involves highlighting a specific area while covering the rest of the page with a semi-transparent black overlay, all using CSS only. What is the most common approach to achieving ...

How can I display an array of data with a changing name using a FlatList in React Native?

How can I render a list of array data with a dynamic name in a FlatList using React Native? Below is the list of data that I would like to display in the FlatList: const movies = [ { '4W2JJ0CLbvfLJzBUHORVaz6sAGv2': [ { name: ...

The function cannot be applied to the size of the map within the action payload

Is there a way to replace the for loop with the map method? The data structure for book.pages is in the format [{},{},{}] I tried using the size method and included this line console.log("book.pages.map.size();--->", book.pages.map.si ...

What is the method to trigger the jQuery 'mouseenter' event on an element using Selenium?

Struggling to automate a scenario using selenium where I need to click on a menu element. I've tried various methods, except jQuery. WebDriver normal click and JavaScript click() haven't worked. Can someone assist me with implementing jQuery in s ...

How to dynamically update data in Angular without the need for a page refresh or loading?

Looking to enhance a wishlist feature by enabling users to delete items from the list without the need for a page refresh. Here's my approach: wish.controller('wishCtrl',['$scope','$http','$cookies','$wind ...

Securing access across multiple routes in a React application

I am facing a challenge in my React app where I need to verify the logged-in state before allowing access to multiple routes. Despite consulting various resources like Stack Overflow for solutions such as creating a Private Route, I have only found example ...

Comparing Embedded and Linked JS/CSS

In my experience, I understand the advantages of using linked CSS over embedded and inline styles for better maintainability and modularity. However, I have come across information suggesting that in certain mobile web development applications, it may be m ...

Access row information within a function while incorporating a data-table component

I am currently facing a challenge with my custom Data-Table being utilized by all developers in the workspace. Due to its complexity, I find it difficult to make changes for minor tasks and have decided to explore alternative solutions. The Data-Table is ...

The Angular modal feature is specifically designed to function exclusively within the index.html

Success! My angular modal is now functioning properly. https://i.sstatic.net/CUHpL.png One thing to note is that the modal script must be placed within my index.html file for it to work: <script type="text/ng-template" id="myModalContent.html"> ...

The use of Handlebars expressions within the {{#each}} block is crucial

I am currently working on my new portfolio site and I have a question about how to place handlebars expressions inside an #each loop. The project is an express application generated by express-generator, and I am using the express-handlebars NPM package: ...

Angular Material Sidenav fails to cover the entire screen while scrolling

https://i.stack.imgur.com/32kfE.png When scrolling, the Sidenav is not expanding to take up 100% of the screen and it continues to scroll along with the page content. <div layout="column"> <section layout="row" flex> <!-- siden ...

Create an HTML table to view JSON data from a cell on a map

Looking to transform the JSON data into a table by organizing the information based on supplier and product. Below is the JSON input and code snippet: $(document).ready(function () { var json = [{ "Supplier": "Supplier1", "Product": "O ...

Ways to prevent the repetition of keys associated with values

I am currently dealing with an array called serialNumbers, which can have different structures. For example: lot: 1 Serial: 2 lot: 1 Serial: 3 lot: 1 Serial: 4 ...or it could look like this: lot: 1 Serial: 5 lot: 1 Serial: 9 lot: 8 Serial: 2 lot: ...

Uh oh! There seems to be an issue with the ClerkJS frontendAPI option. Visit the homepage at https://dashboard.clerk.dev to retrieve your unique Frontend API value

Despite inputting the correct Clerk API keys, I'm encountering issues with the functionality of the ClerkJS API. I anticipate that the application should enable me to utilize the ClerkJS API for user authentication without any problems. ...

Guide to running examples of three.js on a local web browser

Currently, I am attempting to run the examples from three.js locally in a web browser on MacOS. To do this, I have cloned the entire three.js repository and attempted to open a file in a browser (such as three.js/examples/misc_controls_orbit.html). However ...