Как получить доступ к реквизиту слота из компонента, используемого внутри слота?

#vue.js

Вопрос:

поэтому все, что я могу найти о слотах с областью действия и передающих реквизитах, не подходит для моей конкретной ситуации:

у меня есть следующий порядок компонентов:

Главная страница/Список/Список

теперь я решил заменить элемент ListItem на слот, и потому что я использую список и в другом компоненте, но там мне нужен элемент 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.

Комментарии:

1. На самом деле не совсем ясно, чего вы хотите. Что именно вы имеете в виду, говоря, что я не могу заставить его работать, не взорвав свой домашний компонент, как воздушный шар ?

2. я хочу добавить свойства в дочерний компонент, а не в домашний компонент.

3. ну, тогда вы должны передать это через реквизит….

4. ты не можешь. это моя проблема. Вы видите во втором вырезанном коде, что я передаю «:товар=’товар'». но у ребенка нет доступа

5. Нет, вы делаете item его доступным для слота , а не для компонента, используемого внутри слота…

Ответ №1:

Любой компонент, используемый внутри слота с областью действия, не имеет неявного доступа к реквизитам слота. Чтобы сделать их доступными внутри компонента, вы должны явно передать их этому компоненту в качестве реквизитов…

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

Если у вас есть много реквизитов/событий, которые вы хотите передать, возможность как v-bind, так и v-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>
 

Комментарии:

1. это не сработало, потому что показанный вами снимок находится в компоненте Home. Главная-компонент не знает об элементе. элемент будет создан в самом компоненте списка внутри цикла for.

2.Да item находится внутри компонента списка, но он доступен для слота (например, родительский компонент, который использует компонент списка) — так что вы можете использовать item внутри шаблона слота!

3. спасибо вам за ваше терпение. я не совсем понимаю это решение, но я копаюсь в нем. как то, что я могу сказать сейчас: это работает! Спасибо!

4. Просто внимательно прочитайте документы …это очень хорошо объясняет концепцию