Vue.js与子组件的组件通信

时间:2017-11-05 23:29:18

标签: javascript vue.js vuejs2

我想在Vue中创建一个滑块 我有2个组件" Slider"和" SliderItem" A"滑块"可以有多个" SliderItem" s 我如何在内部通过这两个组件进行通信
示例用法

<Slider>
    <SliderItem>
        <h1>Slide 1</h1>
    </SliderItem>
    <SliderItem>
        <h1>Slide 2</h1>
    </SliderItem>
</Slider>

滑块组件

<template>

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

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

如何将当前索引传递给子(SliderItem)
所以我可以根据从父母传递的索引来显示/隐藏它们(Slider)
并以同样的方式我如何实现孩子与父母的沟通
例如在React中,它可以像这样完成

const childrenWithProps = React.Children.map(this.props.children,
 (child) => React.cloneElement(child, {
   index: this.state.index
 })
);


我想在Vue做同样的事情

4 个答案:

答案 0 :(得分:2)

使用props将数据传递给子项,events将数据从子项传递回父项。孩子与孩子之间的沟通是通过家长完成的。

请仔细阅读文档,因为您会找到您需要的大部分内容。祝你好运!

答案 1 :(得分:1)

我认为这会对你有帮助,首先将你的内部组件包装在一个定义了范围的模板中,并将索引作为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>

然后在滑块组件中:

<template>

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

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

然后在sliderItem组件中,你可以像我的道具一样访问索引:

props:['parentIndex']

答案 2 :(得分:0)

正如另一个答案所说,你应该使用道具。我认为你过分关注如何以与vue的反应方式实现你的解决方案。你可以使用React或Vue来完成它,不需要混合它们。 HTML模板代码是由Vue解析的标记,它不是渲染的DOM的一部分,而是处理。

要重新迭代,HTML会转换为JavaScript,因此您的道具将不会在DOM中看到。

答案 3 :(得分:0)

Kumar_14的回答大多是正确的 但他编辑了我不想做的HTML,以使插件的使用尽可能简单和小巧

但我找到了一种更简单的方法,通过使用这个。来自孩子的$ parent来访问父母的数据

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