hyperupcall
hyperupcall

Reputation: 973

Passing data from a component that contains slot content to that slot content component

This is simpler than it sounds. I don't think I know the proper terminology to improve the title.

I want to pass data from a component that contains slot content to that slot content component. Specifically, I have data I want to pass called tier in Sponsors.vue. I want to pass that data to SponsorCard.vue.

Right now, some SponsorCard.vue components are being send to a slot inside a SponsorCardWrapper.vue component within my Sponsors.vue file. I want to use tier inside my SponsorCard.vue component. (Specifically, I want to change the width of the image depending on the tier level of the sponsor, which I can do provided that I send the tier prop).

Sponsors.vue

<template>
  <sponsor-card-wrapper tier="gold">
    <sponsor-card showSponsor="gamma"></sponsor-card>
  </sponsor-card-wrapper>
</template>


SponsorCardWrapper.vue

<template>
  <div class="sponsor-card-wrapper">
    <h2> {{ tier }} </h2>
    <layout-card-overflow :class="tier">
      <slot></slot>
    </layout-card-overflow>
  </div>
</template>


SponsorCard.vue

<template>
  <div class="sponsor">
    <h3> {{ sponsor.name }} </h3>
    <img :src="sponsor.image" :alt="sponsor.imageAltText" width="250px"/>
  </div>
</template>
<script>
  data() {
    computed: {
      sponsor: function() {
        return this.sponsors[this.showSponsor]
      }
    }
  }
</script>

One approach is to pass a prop even single one of my SponsorCard component directly, <sponsor-card tier="gold" showSponsor="gamma"></sponsor-card>. But I don't want to do that because I'd like to just move a SponsorCard component from inside one SponsorCardWrapper to another. I also tried to create scoped slots, but I don't think I'm supposed to be using them here.

Any help would be appreciated. If there is any problems with my description or I need improvements to my terminology, let me know!

Upvotes: 0

Views: 1038

Answers (1)

Blitz
Blitz

Reputation: 500

I think you should use Scoped Slots.

https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots https://medium.com/binarcode/understanding-scoped-slots-in-vue-js-db5315a42391

Something like this:

Sponsors.vue

<template>
  <sponsor-card-wrapper>
    <sponsor-card
      slot-scope="{ tier }"
      :tier="tier"
    ></sponsor-card>
  </sponsor-card-wrapper>
</template>

SponsorCardWrapper.vue

<template>
  <div>
    <h2>title</h2>
    <layout-card-overflow>
      <slot
        v-bind:tier="tier"
      ></slot>
    </layout-card-overflow>
  </div>
</template>
<script>
export default {
  props: ['tier']
}
</script>

SponsorCard.vue

<template>
  <div>
    <h3>{{ tier }}</h3>
  </div>
</template>
<script>
export default {
  props: ['tier']
}
</script>

This is very useful for lists rendering.

In your case, why don't you just do:

<template>
  <sponsor-card-wrapper tier="gold">
    <sponsor-card showSponsor="gamma" tier="gold"></sponsor-card>
  </sponsor-card-wrapper>
</template>

Upvotes: 1

Related Questions