使用 VueJS 中的插槽访问其他组件中的组件数据

Posted

技术标签:

【中文标题】使用 VueJS 中的插槽访问其他组件中的组件数据【英文标题】:Access component data in other component using slots in VueJS 【发布时间】:2018-03-02 15:53:42 【问题描述】:

我正在尝试构建一个 VueJS 组件。我还有两个其他组件,我想以父子方式使用它们。现在,我想将父母的数据传递给孩子。是这样的:

App.vue

<template>
    <div id="app">
        <parent>
            <child></child>
            <child></child>
            <child></child>
            <child></child> 
        </parent>
    </div>
</template>

<script>
    import child from './child.vue'
    import parent from './parent.vue'

    var vm = new Vue(
      el: '#app',
      components: 
        parent,
        child
      
    )  
</script>

父.vue

<template>
    <div class="container">
        This is parent component
        <slot>
        </slot>
    </div>
</template>

<script>
    export default 
        name: 'parent',
        data () 
            return 
                parentMsg: 
                    'key1': 'value1',
                    'key2': 'value2'
                
            
        
    
</script>

child.vue

<template>
    <div class="container">
      Child component
      <!-- I have to place a div here which will consume parentMsg object -->
      <!-- Each instance of child component rendered should have access to parentMsg -->
      <div>
         <!-- Some html to consume the parentMsg -->  
      </div>
    </div>
</template>

<script type="text/javascript">
    export default 
        name: 'child',
        data () 
            return 
                demo: 'Demo message changed'
            
        
    
</script>

我希望parent.vue 中的parentMsg 可以在child.vue 中访问。我不想在App.vue 上暴露parentMsg。我怎样才能做到这一点? 我将使用 parentMsg 的div 放置在 parent.vue 模板中的未命名插槽内(以及之后),并认为对于 child.vue 的每个实例,都会呈现 div 的副本。它不起作用。

【问题讨论】:

为什么不将子组件放在父模板中,然后将消息从父模板传递给它们?插槽不适合这样使用。 【参考方案1】:

你可以在 parent.vue 的 slot 中传递数据

<template>
    <div class="container">
        This is parent component
        <slot :parentMsg="parentMsg"></slot>
    </div>
</template>

在 app.vue 中通过作用域访问 parentMsg 并作为 props 传递给 child:

<template>
    <div id="app">
        <parent>
           <template scope="defaultSlotScope">
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
            <child :msg="defaultSlotScope.parentMsg"></child>
          </template>
        </parent>
    </div>
</template

>

在 child.vue 中使用 msg 作为道具:

<template>
    <div class="container">
      <div>
         msg  
      </div>
    </div>
</template>

<script type="text/javascript">
    export default 
        name: 'child',
        props:['msg'],
        data () 
            return 
                demo: 'Demo message changed'
            
        
    
</script>

【讨论】:

感谢@Kumar_14 的回答。【参考方案2】:

为什么不将子组件放在父模板中,然后将 msg 从父模板传递给它们?插槽不适合这样使用。

App.vue

<template>
    <div id="app">
        <parent>
        </parent>
    </div>
</template>

<script>
    import parent from './parent.vue'

    var vm = new Vue(
      el: '#app',
      components: 
        parent,
        child
      
    )  
</script>

父.vue

<template>
    <div class="container">
        This is parent component
        <child :msg="key1"></child>
        <child :msg="key1"></child>
    </div>
</template>

<script>
    import child from './child.vue'

    export default 
        name: 'parent',
        data () 
            return 
                parentMsg: 
                    'key1': 'value1',
                    'key2': 'value2'
                
            
        
    
</script>

Child.vue

<template>
    <div class="container">
      Child component
      <div>
         msg
      </div>
    </div>
</template>

<script type="text/javascript">
    export default 
        name: 'child',
        props: 
          msg: String
        ,
        data () 
            return 
                demo: 'Demo message changed'
            
        
    
</script>

【讨论】:

我想要实现的有点不同。我创建了一个小提琴:jsfiddle.net/g5oc1rgq/14 您可以看到根组件中的插槽没有插入到相应的子组件中。有什么想法吗? 好的首先我可以看到你在#app元素中插入DOM元素这是完全错误的你首先将根vue组件安装到#app元素 我很快就会给你一个 jsfiddle 非常感谢。我也为此添加了一个新问题。 ***.com/questions/46344908/…您可以查看更多详情。 你能做一个小提琴吗?

以上是关于使用 VueJS 中的插槽访问其他组件中的组件数据的主要内容,如果未能解决你的问题,请参考以下文章

使用插槽移动传递到组件中的元素

Vuejs之Component slot 插槽详解

如何在混合 VueJS 应用程序上使用(命名)插槽

VueJS 从根 Vue 实例中的组件访问数据

如何封装/包装一个 VueJS 组件?

如何在 VueJS 中的组件之间共享数据