【问题标题】:Vue.js component communication with children componentsVue.js 组件与子组件的通信
【发布时间】:2018-04-18 01:45:02
【问题描述】:

我想在 Vue 中做一个滑块 我有 2 个组件“Slider”和“SliderItem” 一个“Slider”可以有多个“SliderItem” 我如何在这两个组件之间进行内部通信
示例用法

<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)
所以我可以根据从父级(滑块)传递的索引显示/隐藏它们
以及如何实现孩子与父母的交流
例如在 React 中可以这样做

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


我想在 Vue 中做同样的事情

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    使用props 将数据向下传递给子级,使用events 将数据从子级传递回父级。子与子之间的通信是通过父级完成的。

    请仔细研究文档,因为您会在其中找到所需的大部分内容。祝你好运!

    【讨论】:

    • 我已经知道基本的通信如何使事件上升和下降,包括事件总线。我的问题是如何在内部实现组件到子组件的通信。上面的示例代码。
    • 我不明白你的内部是什么意思,你能澄清更多吗?
    • 例如,在 Slider 组件中,我如何将 (index) 传递给它的 (SliderItem) 子级。我在内部的意思是我不想更改 HTML 代码我希望通信仅在 (Slider) 和 (SliderItem) 之间进行
    • 除了使用 props/events、事件总线或 vuex,我真的不知道。我仍然不明白您是如何遇到传递道具/事件不是解决方案的情况,因为它是组件间通信的主要内容。
    【解决方案2】:

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

    为了重新迭代,HTML 被转换为 JavaScript,所以你的 props 不会在 DOM 中看到。

    【讨论】:

      【解决方案3】:

      我认为这会对你有所帮助,首先将你的内部组件包装在一个定义了范围的模板中,并为内部组件提供索引作为 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 组件中,您可以访问 index 作为 i prop:

      props:['parentIndex']
      

      【讨论】:

        【解决方案4】:

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

        但我找到了一种更简单的方法,方法是使用来自孩子的 this.$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

        【讨论】:

          猜你喜欢
          • 2015-10-29
          • 2017-10-05
          • 2018-06-30
          • 2017-12-25
          • 2018-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多