如何使组件道具可用于其开槽元素?

Posted

技术标签:

【中文标题】如何使组件道具可用于其开槽元素?【英文标题】:How to make a components prop available to its slotted elements? 【发布时间】:2018-09-15 00:42:01 【问题描述】:

我有这样的结构:

<childs>
    <child>
        <ul>
          <li v-for="item in currentData">@ item.name </li>
        </ul>
    </child>
</childs>

child 组件中,我有一个数据属性currentData

// Child.vue
data: 
    currentData: 

出于某种原因,我从childs 组件(而不是child)为这个currentData 属性赋值。

// Childs.vue
child.currentData = data;

如何使currentData 可用于&lt;child&gt; 的开槽元素:

<ul>
    <li v-for="item in currentData">@ item.name </li>
</ul>

Child.vue 的模板是这样的:

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

我尝试过这样的事情:

<template> <div><slot :current-data="currentData"></slot></div> </template>

【问题讨论】:

How to pass props using slots from parent to child -vuejs的可能重复 @ShubhamPatel 该问题的答案并不能解决我的问题。我不想为我的每个child 组件使用template 标签。 【参考方案1】:

我相信你需要的是Scoped Slots

为此,您应该明确地传递(在模板的插槽声明中)您想要提供给&lt;slot&gt;“用户”的道具。

例如假设您想让foo 的插槽用户可以使用foo 属性(假设childData 属性存在于&lt;child&gt; 中)。你会这样做:

<!-- This is <child>'s template -->
<template> <div><slot :foo="childData"></slot></div> </template>

从那时起,任何使用&lt;child&gt; 组件的人都可以通过声明slot-scope 来访问foo 属性:

<child>
  <ul slot-scope="slotProps">
    <li> slotProps.foo </li>
  </ul>
</child>

请注意,slot-scope 是在替换 &lt;slot&gt; 所在位置的元素中声明的。

完整演示:

Vue.component('children', 
  template: '#children'
)

Vue.component('child', 
  template: '#child',
  data() 
    return 
      childData: "I am childData"
    
  
)

new Vue(
  el: '#app'
)
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <children>
    <child>
      <ul slot-scope="slotProps">
        <li> slotProps.foo </li>
        <!-- <li v-for="item in currentData">@ item.name </li> -->
      </ul>
    </child>
  </children>
</div>

<template id="children">
  <div><slot></slot></div>
</template>
<template id="child">
  <div><slot :foo="childData"></slot></div>
</template>

如果我想在&lt;ul&gt; 元素之外添加另一个元素怎么办? Vue 会简单地丢弃 slot-scope 之外的任何内容。

这不是因为slot-scope,而是因为&lt;slot&gt;s。

由于child 只有一个&lt;slot&gt;,因此您在&lt;child&gt; 中放置的第一个元素将采用slot

如果您想让多个元素采用slot,则必须将它们包装起来。例如。在&lt;div&gt;。但是,如果您不希望呈现此包装器元素,请使用&lt;template&gt;。请参阅下面的演示。

Vue.component('children', 
  template: '#children'
)

Vue.component('child', 
  template: '#child',
  data() 
    return 
      childData: "I am childData"
    
  
)

new Vue(
  el: '#app'
)
.child  border: 1px solid red 
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <children>
    <child>
      <template slot-scope="slotProps">
        <ul>
          <li> slotProps.foo </li>
          <!-- <li v-for="item in currentData">@ item.name </li> -->
        </ul>
        <span>howdy</span>
      </template>
    </child>
  </children>
</div>

<template id="children">
  <div><slot></slot></div>
</template>
<template id="child">
  <div class="child"><slot :foo="childData"></slot></div>
</template>

【讨论】:

如果我想在&lt;ul&gt; 元素之外添加另一个元素怎么办? Vue 只是丢弃了 slot-scope 之外的任何东西。

以上是关于如何使组件道具可用于其开槽元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何使变量可用于组件中的每个方法?

reactjs中如何将可选元素作为prop传递给组件

父元素的入队React更新是否也总是更新子元素吗?

如何在带有样式组件的伪元素上传递道具?

使用样式化组件时如何保留原始 html 元素的道具?

如何在不将道具传递给底层 DOM 元素的情况下扩展样式组件?