Vue Component Communication Methods

Vue Component Communication Techniques

Props and Events (Parent-Child Communication)

Parent components pass data to child components via props, while child components communicate with parents using events.

Parent to Child Data Flow

Props establish one-way data binding from parent to child. When parent data changes, child components automatically update.


// Parent Component
<template>
  <div class="parent-container">
    <child-component :user-data="userInfo" :action-handler="processAction"></child-component>
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue";
export default {
  name: "ParentComponent",
  data() {
    return {
      userInfo: "Parent component information"
    };
  },
  methods: {
    processAction() {
      console.log("Processing action in parent");
    }
  },
  components: {
    ChildComponent
  }
};
</script>

// Child Component
<template>
  <div class="child-container">
    <p>{{ userData }}</p>
    <button @click="actionHandler">Execute Action</button>
  </div>
</template>

<script>
export default {
  name: "ChildComponent",
  props: ["userData", "actionHandler"]
};
</script>

Child to Parent Communication

Child components emit custom events that parent components listen for using v-on directives.


// Parent Component
<template>
  <div class="main-section">
    <book-list :books="bookCollection" @item-selected="handleSelection"></book-list>
    <p>Selected Index: {{ selectedIndex }}</p>
  </div>
</template>

<script>
import BookList from './components/BookList.vue'
export default {
  name: 'BookApp',
  components: { BookList },
  data() {
    return {
      selectedIndex: -1,
      bookCollection: ['Pride and Prejudice', 'Moby Dick', 'Great Expectations']
    }
  },
  methods: {
    handleSelection(index) {
      this.selectedIndex = index
    }
  }
}
</script>

// Child Component
<template>
  <div>
    <div v-for="(book, index) in books" :key="index" @click="selectItem(index)">{{ book }}</div>
  </div>
</template>

<script>
export default {
  props: ['books'],
  methods: {
    selectItem(index) {
      this.$emit('item-selected', index)
    }
  }
}
</script>

Event Bus Pattern

Event buses facilitate communication between any components, regardless of their relationship hierarchy.


// Event bus setup
import Vue from 'vue'
export const EventChannel = new Vue()

// Component emitting event
<template>
  <div>
    <button @click="incrementCounter">Increase Count</button>    
  </div>
</template>

<script>
import {EventChannel} from './event-channel.js'
export default {
  data(){
    return{
      counter: 0
    }
  },
  methods:{
    incrementCounter(){
      EventChannel.$emit('counter-increase', {
        count: this.counter++
      })
    }
  }
}
</script>

// Component receiving event
<template>
  <div>Total Count: {{ total }}</div>
</template>

<script>
import { EventChannel } from './event-channel.js'
export default {
  data() {
    return {
      total: 0
    }
  },
  mounted() {
    EventChannel.$on('counter-increase', params => {
      this.total = this.total + params.count;
    })
  }
}
</script>

Dependency Injetcion (Provide/Inject)

This method enables deep component tree communication without explicit prop passing through intermediate components.


// Ancestor component providing data
provide() { 
    return {     
        sharedData: this.sharedValue  
    };
}

// Descendant component receiving data
inject: ['sharedData']

// Alternative approach accessing entire component instance
provide() {
  return {
    rootComponent: this
  };
}
data() {
  return {
    sharedValue: 'shared information'
  };
}

inject: ['rootComponent']
console.log(this.rootComponent.sharedValue)

Component References

Direct component instance access enables method calls and property access between parent and child components.


// Child component definition
export default {
  data () {
    return {
      componentName: 'Vue Component'
    }
  },
  methods: {
    showMessage () {
      console.log('Component method executed')
    }
  }
}

// Parent component usage
<template>
  <child-comp ref="childReference"></child-comp>
</template>
<script>
  import ChildComp from './ChildComp.vue'
  export default {
    components: { ChildComp },
    mounted () {
      console.log(this.$refs.childReference.componentName);
      this.$refs.childReference.showMessage();
    }
  }
</script>

Parent and Children Instance Access

Components can directly access their parent or children instances through special Vue properties.


// Child component accessing parent
<template>
  <div>
    <span>{{ componentMessage }}</span>
    <p>Parent value: {{ parentValue }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      componentMessage: 'Component data'
    }
  },
  computed:{
    parentValue(){
      return this.$parent.parentData;
    }
  }
}
</script>

// Parent component modifying child
<template>
  <div class="container">
    <div>{{ parentData }}</div>
    <child-comp></child-comp>
    <button @click="updateChild">Update Child Data</button>
  </div>
</template>

<script>
import ChildComp from './ChildComp.vue'
export default {
  components: { ChildComp },
  data() {
    return {
      parentData: 'Initial data'
    }
  },
  methods: {
    updateChild() {
      this.$children[0].componentMessage = 'Updated data'
    }
  }
}
</script>

Attribute and Listener Inheritance

These features enable cross-component communication by inheriting attributes and event listeners.


// Root component
<template>
  <div id="application">
    <intermediate-comp :data-prop="firstData" :secondary-prop="secondData" @first-event="handleFirst" @second-event="handleSecond"></intermediate-comp>
  </div>
</template>
<script>
import IntermediateComp from './IntermediateComp.vue';
export default {
  components: { IntermediateComp },
  methods: {
    handleFirst() {
      console.log('First event handled');
    },
    handleSecond() {
      console.log('Second event handled');
    }
  }
};
</script>

// Intermediate component
<template>
  <div class="middle-component">
    <p>Props: {{ dataProp }}</p>
    <p>Attributes: {{ $attrs }}</p>
    <final-component v-bind="$attrs" v-on="$listeners"></final-component>
  </div>
</template>
<script>
import FinalComponent from './FinalComponent.vue';
export default {
  props: ['dataProp'],
  components: { FinalComponent },
  inheritAttrs: false,
  mounted() {
    this.$emit('first-event');
  }
};
</script>

// Final component
<template>
  <div class="end-component">
    <p>Props: {{ secondaryProp }}</p>
    <p>Attributes: {{ $attrs }}</p>
  </div>
</template>
<script>
export default {
  props: ['secondaryProp'],
  inheritAttrs: false,
  mounted() {
    this.$emit('second-event');
  }
};
</script>

Tags: Vue.js Component Communication Props Emit Event Bus

Posted on Sun, 28 Jun 2026 17:53:35 +0000 by ozzysworld