首页 > 解决方案 > 如何从插槽内使用的组件访问插槽道具?

问题描述

所以我能找到的关于作用域插槽和传递道具的所有内容都不适用于我的具体情况:

我有以下组件顺序:

主页/列表/列表项

现在我决定用一个插槽替换 ListItem,因为我也在其他组件中使用了 List,但在那里我需要 ListOptionsItem。

在我的家庭组件中,我这样做了:

               <list 
                class="mapkeyList"
                :content="displayList"
                :filterbar="true"
                @handleSelection="addSelection"
                @delete="deleteElement"
                @editItem="editItem"
                header="Mapkeys"
                :key="mapkeyListKey"
           >
                <list-item>
                </list-item>
           </list>

在我的列表组件中,我有这个:

<template>
 <div>
      <h2 v-if="header">{{header}}</h2>
      <div  class="listContainer"  v-if="showedContent.length > 0">
           
           <div v-for=" (item, index) in showedContent" :key="index">
                <slot 
                     :item="item"
                     :index="index"
                     :dragable="dragableItems"
                     @auswahl="auswahlHandle"
                     @deleteElement="deleteElement"
                     @editItem="editItem"
                     :dontShowButtons="dontShowButtons"
                     @dragStart="handleOverDragStart"
                     :dragItem="dragItem"
                     @position="$emit('emitPosition',item)"
                     :deaktivierbar="deaktivierbar"
                >
                </slot >
           </div>

最后 listItem 和 listOptionsItem 需要在插槽中访问此道具:

项目清单:

<template>
 <div class= "flexSpaceBetween" @click="$emit('auswahl',item)">
      <div class="textFett">
           {{item[0]}}
      </div>
      <div>
           {{item[1]}}
      </div>
 </div>

我不想在 home 组件中编写所有必需的代码,因为 listOptionsItem 确实需要更多信息和更多空间来编写代码。

我的目标是在 Home 组件中定义我希望列表使用 listItem 组件,而在 Options 组件中,列表应该使用 listItemOptions 组件。将来可能会添加新的 listItem 版本。

标签: vue.js

解决方案


在作用域插槽内使用的任何组件都没有对插槽道具的隐式访问。要使它们在组件可用,您必须将其作为道具明确传递给该组件......

<list 
  class="mapkeyList"
  :content="displayList"
  :key="mapkeyListKey">
  <template v-slot:default="{ item }">
    <list-item :item="item">
    </list-item>
  </template>
</list>

如果您有很多要传递的道具/事件,v-bindv-on将对象作为参数的能力非常有用,因为您可以同时传递所有数据和事件处理程序:

// List component
<template>
<div>
  <h2 v-if="header">{{header}}</h2>
  <div  class="listContainer"  v-if="showedContent.length > 0">
        
    <div v-for=" (item, index) in showedContent" :key="index">
       <slot :props="slotProps" :on="slotEventsHandlers"
       </slot >
    </div>
  </div>
</div>
</template>

<script>
export default {
  computed: {
    slotProps() {
      return {
        item: this.item,
        dragable: this.dragableItems
      }
    },
    slotEventsHandlers() {
      return {
        deleteElement: this.deleteElement,
        dragStart: this.handleOverDragStart
      }
    }
  }
}
</script>

并在父母中使用它:

<list 
  class="mapkeyList"
  :content="displayList"
  :key="mapkeyListKey">
  <template v-slot:default="{ props, on }">
    <list-item v-bind="props" v-on="on">
    </list-item>
  </template>
</list>

推荐阅读