【问题标题】:How to make parent aware of child components inside slot?如何让父母知道插槽内的子组件?
【发布时间】:2018-06-17 23:11:48
【问题描述】:

我想知道如何让父组件知道插槽内的子组件。

例如,如果我想创建一个滑块并且我希望具有以下结构:

在我看来:

<vue-slider>
    <vue-slide name="First slide!">First slide content</vue-slide>
    <vue-slide name="Second slide!">Second slide content</vue-slide>
</vue-slider>

VueSlider.vue

<template>
    <div class="slider">
        <ol>
            <li v-for="(slide,index) in slides">{{slide.name}}</li>
        </ol>


        <slot></slot>
    </div>
</template>

<script>
    export default {

        data: function(){
          return {
              slides: [],
          }
        }
    }
</script>

VueSlide.vue

<template>
    <div class="slide">
        <slot></slot>
    </div>
</template>

<script>
    export default {
        props: {
            'name': {

            }
        }
    }
</script>

所以我想在父组件上填充幻灯片数组。我正在考虑在安装每张幻灯片时发出一个事件,但后来我在 vue 文档上阅读了这个:

您不能使用 $on 来监听孩子发出的事件。您必须在模板中直接使用 v-on,如下例所示。

谢谢!

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component


    【解决方案1】:

    默认插槽中的所有内容都可通过组件内的$slots.default 获得(命名插槽可通过$slots[name] 获得)。因此,如果您想在父组件中填充 slides 数组,您可以检查默认插槽的内容并消除不是幻灯片的节点(包括回车等空格作为节点)。

    这是一个例子。

    console.clear()
    
    Vue.component("VueSlider", {
      template: `
        <div class="slider">
           <h1>Number of slides: {{slides.length}}</h1>
            <ol>
                <li v-for="(slide,index) in slides">{{slide.name}}</li>
            </ol>
            <slot></slot>
        </div>
      `,
      data: function() {
        return {
          slides: [],
        }
      },
      mounted(){
        for (let node of this.$slots.default){
          // filter out whitespace nodes
          if (node.tag){ 
            // may want to check to add only VueSlide nodes
            this.slides.push(node.componentInstance)
          }
        }
      }
    })
    
    Vue.component("VueSlide", {
      template: `
        <div class="slide">
            <slot></slot>
        </div>
      `,
      props: {
        'name': String
      }
    })
    
    new Vue({
      el: "#app"
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
    <div id="app">
      <vue-slider>
        <vue-slide name="First slide!">First slide content</vue-slide>
        <vue-slide name="Second slide!">Second slide content</vue-slide>
      </vue-slider>
    </div>

    您需要检查node 对象,以便查看属性是什么。在这种情况下,我将componentInstance 推送到幻灯片数组中,因为这是当前组件实例的数据属性所在的位置(因此您可以在父级中使用{{slide.name}}。在我这样做的情况下,但是,我通常会将自定义对象推送到仅包含我想要的信息的集合中。像这样:

    this.slides.push({name: node.componentInstance.name})
    

    【讨论】:

    • 非常感谢您的详细回复。正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2021-05-27
    • 2020-01-30
    • 2021-07-28
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    相关资源
    最近更新 更多