Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering VUE slot only if content matches specific value

I have two routes that render the same component but with different data coming from an API. This component has a child component called <base-section> that has a v-if directive that checks if a specific slot has content or not (because if it has no content, I don't want the slot to show).

However, there might be more than one instance of this child component on the same parent component, and therefore, if one of the instances has content in the slot, but the other one doesn't, VUE will automatically assume that all slots have content.

Therefore, I would like to know if there is any way of checking the specific slot content of each instance and then compare it with the data coming from the API. Please find my code below:

Parent component (Content.vue)

<template>
  <base-section
    v-for="entry in this.entries"
    :key="entry.title"
    lang="lang-markup"
    :title="entry.title"
  >
    <template v-slot:content>
        <span v-html="entry.content"></span>
    </template>
    <template v-slot:examples>
      <div v-html="entry.examples"></div>
    </template>
    <template v-slot:code>
      {{ entry.code }}
    </template>
  </base-section>
</template>

Child component (BaseSection.vue)

<template>
  <hr class="my-6" />
  <h4 class="text-salmon">{{ title }}</h4>
  <section>
    <div class="section-sm txt-justify" v-if="this.$slots.content">
      <slot name="content"></slot>
    </div>
    <span class="medal bg-light text-dark code-medal">Examples</span>
    <div class="section-sm border-light-1 mb-3">
      <slot name="examples"></slot>
    </div>

    <span class="medal text-dark code-medal">Code</span>
    <pre :class="lang + ' border-light-1 bg-light'"> 
<code><slot name="code"></slot></code>
</pre>
  </section>
</template>

The data coming from the API follows this structure:

getData() {
      const url = this.apiUrl + this.$route.name + this.apiToken
      fetch(url)
        .then((collection) => collection.json())
        .then((collection) => {
          const entries = [];
          this.entries = [];

          for (const id in collection.entries) {
            if (collection.entries[id].Version === this.byteVersion) {
              entries.push({
                title: collection.entries[id].Title,
                content: collection.entries[id].Content,
                examples: collection.entries[id].Examples,
                code: collection.entries[id].Code,
              });
            }
          }

          this.entries = entries;
        });
    }

Thank you very much for your help!

Regards, T.

like image 317
Slaveworx Avatar asked Oct 30 '25 02:10

Slaveworx


1 Answers

Maybe you can pass the "entry.content" into your BaseSection component. and v-if the entryContent.

Parent component (Content.vue)

<template>
  <base-section
    v-for="entry in this.entries"
    :key="entry.title"
    lang="lang-markup"
    :title="entry.title"
    :entryContent="entry.content"
    >
    <template v-slot:content>
        <span v-html="entry.content"></span>
    </template>
    <template v-slot:examples>
      <div v-html="entry.examples"></div>
    </template>
    <template v-slot:code>
      {{ entry.code }}
    </template>
  </base-section>
</template>

Child component (BaseSection.vue)

<div class="section-sm txt-justify" v-if="entryContent">
   <slot name="content"></slot>
</div>

Or you can v-if your content template

    <template v-slot:content v-if="entry.content">
        <span v-html="entry.content"></span>
    </template>
like image 186
markcc Avatar answered Oct 31 '25 17:10

markcc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!