【问题标题】:Rendering VUE slot only if content matches specific value仅当内容与特定值匹配时才渲染 VUE 槽
【发布时间】:2021-03-07 05:13:48
【问题描述】:

我有两条路线,它们呈现相同的组件,但具有来自 API 的不同数据。 该组件有一个名为 <base-section> 的子组件,它有一个 v-if 指令,用于检查特定插槽是否有内容(因为如果它没有内容,我不希望该插槽显示)。

但是,在同一个父组件上可能有多个该子组件的实例,因此,如果其中一个实例在槽中有内容,而另一个没有,VUE 将自动假定所有插槽有内容。

因此,我想知道是否有任何方法可以检查每个实例的特定插槽内容,然后将其与来自 API 的数据进行比较。请在下面找到我的代码:

父组件(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>

子组件(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>

来自 API 的数据遵循以下结构:

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;
        });
    }

非常感谢您的帮助!

问候, T.

【问题讨论】:

  • 你不需要在模板中使用this,尝试删除它们,即v-if="$slots.content",看看它是否有效
  • 你好丹尼尔。不幸的是,它不起作用。它一直假设插槽有内容,并一直显示为有内容的部分设置的默认边距和填充参数。

标签: javascript vue.js vue-router vuejs3


【解决方案1】:

也许您可以将“entry.content”传递到您的 BaseSection 组件中。和 v-if 条目内容。

父组件(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>

子组件(BaseSection.vue)

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

或者你可以 v-if 你的内容模板

    <template v-slot:content v-if="entry.content">
        <span v-html="entry.content"></span>
    </template>

【讨论】:

  • 完美!它就像一个魅力。它是如此简单,它一直在我面前。感谢您的贡献。对于那些可能有同样问题的人,我直接在父级中做了 v-if 我的内容模板,这样内容槽中就没有任何内容(甚至没有代码 html)。谢谢!
猜你喜欢
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 2020-05-16
  • 2019-08-17
  • 2021-04-03
  • 1970-01-01
相关资源
最近更新 更多