0

Consider the following in a component snipet:

<tr v-for="row in rows" :key="row[rowKey]">
   <td v-for="col in cols">
      <slot v-if="col.bSlot" :name="col.bSlot" :row="row"></slot>
      <template v-else v-html="formatField(row, col)"></template>
   </td>
</tr>

Above I want to render a slot if given and if not to render a string returned by a formatting function unescaped. This did not work because I found out that v-html does not work with templates. The following works but you need extra unnecessary div tags that I don't want:

<td v-for="col in cols">
   <slot v-if="col.bSlot" :name="col.bSlot" :row="row"></slot>
   <div v-else v-html="formatField(row, col)"></div>
</td>

It would be nice if this still worked but has been deprecated:

<td v-for="col in cols">
   <slot v-if="col.bSlot" :name="col.bSlot" :row="row"></slot>
   <template v-else>
      {{{formatField(row, col)}}}
   </template>
</td>

The only other option I am left with is this but because there is no where to put the v-else I made the formatField() return nothing if a slot is given:

<td v-for="col in cols" v-html="formatField(row, col)">
   <slot v-if="col.bSlot" :name="col.bSlot" :row="row"></slot>
</td>

formatField(row, col) {
   if (col.bSlot) return;  // also tried returning null, undefined, and ''
   ...
}

However now the slot doesn't render when one is provided. It seems like Vue ignores the slot if v-html is provided. So how do I not provide v-html when the col.bSlot is not provided?

Brobic Vripiat
  • 176
  • 2
  • 12
  • 2
    Does this answer your question? [VueJS conditionally add an attribute for an element](https://stackoverflow.com/questions/42874314/vuejs-conditionally-add-an-attribute-for-an-element) – Bryan Oct 29 '19 at 21:59
  • No, I don't see how its in any way related other than matching on key words. Read my post carefully and you'll see its a different question. – Brobic Vripiat Oct 30 '19 at 00:49

1 Answers1

0

You can place default value if slot is not given - Fallback-Content

How about this:

1 <td v-for="col in cols">
2  <slot :name="col.bSlot" :row="row">
3     {{ formatField(row, col) }}
4     // <-- this is a comment
5     // <span v-html="formatField(row, col)"></span>
6   </slot>
7 </td>
tony19
  • 125,647
  • 18
  • 229
  • 307
Adam Orłowski
  • 4,268
  • 24
  • 33
  • Isn't this the same as the second code sample I have above that explains this solution with the caveat that there would be an unnecessary element added (
    in my case and in yours). That's what I did not like about that solution and was looking for one without the unnecessarily added elements.
    – Brobic Vripiat Oct 30 '19 at 19:19
  • @BrobicVripiat use line 3 then `{{ formatField(row, col) }}`. And in your `formatField` method `return` string you need. – Adam Orłowski Oct 30 '19 at 21:53