[Vuejs]-Vue.js component communication with children components

0👍

Kumar_14’s answer is mostly correct
but he edited the HTML which I didn’t want to do in order to make the usage of the plugin as simple and small as possible

But I found an easier way to do it by using this.$parent from the child to access the parent’s data

HTML

<div id="root">
  <slider>
    <slider-item :key="1">
      <h1>Slide 1</h1>
    </slider-item>
    <slider-item :key="2">
      <h1>Slide 2</h1>
    </slider-item>
    <slider-item :key="3">
      <h1>Slide 3</h1>
    </slider-item>
    <slider-item :key="4">
      <h1>Slide 4</h1>
    </slider-item>
  </slider>
</div>

JavaScript

var Slider = Vue.component("slider", {
  template: "<div><button @click=\"prev\">Prev</button><slot></slot><button @click=\"next\">Next</button></div>",
  data() {
    return { index: 1 };
  },
  methods: {
    next() {
      this.index = this.index === this.childrenLength ? 1 : this.index + 1;
    },
    prev() {
      this.index = this.index === 1 ? this.childrenLength : this.index - 1;
    }
  },
  computed: {
    childrenLength() {
      return this.$children.length;
    }
  }
});

var SliderItem = Vue.component("slider-item", {
  template: "<div v-if=\"$vnode.data.key === $parent.index\"><slot></slot></div>"
});

new Vue({
  el : "#root",
  components: {
    "slider": Slider,
    "slider-item": SliderItem
  }
});

JSBin

2👍

Use props to pass data down to the children, and events to pass data from the children back to the parent. Child to child communication is done via the parent.

Please study the docs carefully as you will find most of the things you need there. Good luck!

👤8bit

1👍

I think this will help you, first wrap your inner components in a template with a scope defined, as and provide the inner components the index as prop,

<Slider>
   <template scope="sliderItemScope">
     <SliderItem :parent-index="sliderItemScope.i">
        <h1>Slide 1</h1>
     </SliderItem>
     <SliderItem :parent-index="sliderItemScope.i">
        <h1>Slide 2</h1>
     </SliderItem>
   </template>
</Slider>

Then in slider component:

<template>

    <div>
        <slot :i="index"></slot>
    </div>
</template>

<script>
export default {
    data() {
        return { index : 0 };
    }
};
</script>

Then in sliderItem component you can access index as i prop:

props:['parentIndex']

0👍

As the other answer already said, you should use props. I think you’re focusing too much on how to implement your solution in a react way with vue. You can do it using React or Vue, no need to mix them. The HTML template code is a markup that gets parsed by Vue, it will NOT be part of the rendered DOM but instead handled.

To re-iterate, the HTML gets converted to JavaScript, so your props will not be seen in the DOM.

👤Daniel

Leave a comment