如何使用vuejs中的插槽将props从父组件传递到子组件

32
我有一个父组件和一个子组件。 父组件的模板使用插槽,以便可以将一个或多个子组件包含在父组件中。 子组件包含一个名为“signal”的prop。 我希望能够更改父组件中称为“parentVal”的数据,以便将子组件的signal prop更新为父组件的值。
这似乎应该是一些简单的事情,但我无法通过使用插槽来实现它:
以下是一个运行示例:
const MyParent = Vue.component('my-parent', {
  template: `<div>
               <h3>Parent's Children:</h3>
               <slot :signal="parentVal"></slot>
             </div>`,

  data: function() {
    return {
      parentVal: 'value of parent'
    }
  }
});

const MyChild = Vue.component('my-child', {
  template: '<h3>Showing child {{signal}}</h3>',
  props: ['signal']
});

new Vue({
  el: '#app',
  components: {
    MyParent,
    MyChild
  }
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <my-parent>
    <my-child></my-child>
    <my-child></my-child>
  </my-parent>
</div>

3个回答

48
你需要使用一个作用域插槽。你已经接近成功了,我只是添加了创建作用域的模板。
  <my-parent>
    <template slot-scope="{signal}">
      <my-child :signal="signal"></my-child>
      <my-child :signal="signal"></my-child>
    </template>
  </my-parent>

这是您的更新后的代码。

const MyParent = Vue.component('my-parent', {
  template: `<div>
               <h3>Parent's Children:</h3>
               <slot :signal="parentVal"></slot>
             </div>`,

  data: function() {
    return {
      parentVal: 'value of parent'
    }
  }
});


const MyChild = Vue.component('my-child', {
  template: '<h3>Showing child {{signal}}</h3>',
  props: ['signal']
});

new Vue({
  el: '#app',
  components: {
    MyParent,
    MyChild
  }
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <my-parent>
    <template slot-scope="{signal}">
      <my-child :signal="signal"></my-child>
      <my-child :signal="signal"></my-child>
    </template>
  </my-parent>
</div>


Vue 2.6发布引入了一个统一的v-slot指令,可用于普通或作用域插槽。在这种情况下,由于您使用的是默认的未命名插槽,因此可以通过v-slot = "{signal}"访问signal属性:

  <my-parent>
    <template v-slot="{ signal }">
      <my-child :signal="signal"></my-child>
      <my-child :signal="signal"></my-child>
    </template>
  </my-parent>

1
刚刚,Vue 2.6 版本新增了新的插槽语法,这正是他们在 v3 中将支持的。因此,在这种情况下,使用 v-slot="{ signal }"。虽然 slot-scope 仍然受支持。 - thanksd
如果我理解正确的话,较新的语法是用于命名插槽而不是作用域插槽?@thanksd - Bert
1
@thanksd 哦,好的,我明白了。我今晚稍后会更新答案,或者如果你想的话,你也可以先行动。https://medium.com/the-vue-point/vue-2-6-released-66aa6c8e785e - Bert
4
有没有方法可以在“app”文件中不必写入“v-slot”和“:signal”,而是直接将其集成到“my-parent”和“my-child”模板中,以便我只需在应用程序中为父级添加“signal”属性,我的子级就可以自动访问它。 - mesqueeb
1
@mesqueeb 对于这种情况,最好的选择似乎是使用依赖注入,请参阅 https://vuejs.org/v2/guide/components-edge-cases.html#Dependency-Injection - hariseldon78
显示剩余2条评论

1

我将这段代码添加到了<v-data-table></v-data-table>内部

<template
  v-for="slot in slots"
  v-slot:[`item.${slot}`]="{ item }"
>
  <slot
    :name="slot"
    :item="item"
  />
</template>

我添加了一个名为slots的props。当我调用组件时,我会发送一个类似于slots的参数:
<my-custom-table-component :slots="['name']">

 <template v-slot:name="{ item }">
  {{ item.first_name + item.last_name}}
 </template>

</my-custom-table-component>

1
你可以尝试这个技巧。
在这个例子中,假设父组件想要共享属性 foo 的值 bar。
父组件。
<parent>
    <template v-slot:default="slotProps">
        // You can access props as object slotObjects {foo"bar"}
        <p>{{slotProps.foo}}</p>
    </template>
<parent>

子元素

<template>
    <div class="parent">
        <slot :foo="bar" />
    </div>
</template>

这个视频中得到了灵感。

希望它能帮助你完成任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接