19

I'd like to learn what is the best way to conditionally render an HTML attribute in Vue.js. For example, add data-toggle="tooltip" if there is a tooltip message for current instance.

The code I have now:

<span
  :data-toggle="!!col.col_spec.tooltip ? 'tooltip' : ''"
  :title="col.col_spec.tooltip"
>
  {{ col.col_spec.title }}
</span>

Though, I don't like the 2nd line much… Even if I use computed property here, I'd prefer not to have data-toggle attribute at all, when there is no tooltip to display.

pilat
  • 1,094
  • 1
  • 10
  • 17
  • 1
    If you don't want the attribute to exist at all when there is no tooltip, then I would probably not do this in the template, but rather in mounted() or something like that. – Bert Jan 16 '17 at 17:28
  • @str not exactly. It's a bit simpler with "required", which is a "boolean attribute". My question concerns "attributes in general". – pilat May 28 '18 at 07:52
  • @pilat No, it is exactly the same. While `required` indeed is a [boolean attribute](https://html.spec.whatwg.org/#boolean-attribute), you can not pass a `false` value to it. "*The presence of a boolean attribute on an element represents the true value, and the absence of the attribute represents the false value.*" The only way to use it is to either have it in the DOM, or don't. – str May 28 '18 at 07:59
  • Well, it looks that no matter what type of attribute it is, it won't be rendered if it's has 'false' passed to it. Exactly what I needed! https://jsbin.com/lamudoqucu/edit?html,js,output – pilat May 29 '18 at 09:53

4 Answers4

33

Very so elegant solution:

<span
  :data-toggle="!!col.col_spec.tooltip ? 'tooltip' : false"
  :title="col.col_spec.tooltip"
>
  {{ col.col_spec.title }}
</span>

Yes, yes, yes, it's just necessary that there is not an empty string, but a Boolean false

arkadij_ok
  • 505
  • 4
  • 7
  • 7
    This answer is the only good and [officially recommended](https://vuejs.org/v2/guide/syntax.html#Attributes) way to add an attribute conditionally. To remove the attribute, though, it does not necessarily have to be `false`, but could also be `null` or `undefined`. – str May 25 '18 at 13:35
5

Something like:

<span ref="column">
  {{ col.col_spec.title }}
</span>

And in Vue:

mounted(){
    if (this.col.col_spec.tooltip){
      this.$refs.column.setAttribute("data-toggle", this.col.col_spec.tooltip);
    }
}
Bert
  • 80,741
  • 17
  • 199
  • 164
  • 1
    Very clean way of doing it – Baldráni Nov 29 '17 at 16:19
  • the attribute wouldn't be at all reactive if `this.col.col_spec.tooltip` changed... and sometimes components don't re-mount eg. if vue-router stays on the same route/page (same components) but goes to a new page (different data/url). Like navigating from `#/post/1` to `#/post/2`. – Ryan Taylor Nov 07 '19 at 19:10
3

A bit late, but here is my take on it:

HTML:

<span
  :data-toggle="tooltip"
  :data-original-title="tooltipTitle"
>
  {{ tooltipTitle }}
</span>

Vue:

methods: {
    tooltipTitle: function() {
        var title = this.col.col_spec.title;
        if (!!title) return title;
        return false;
    }
}

This will remove the "data-original-title" attribute if there is none to display, consequently removing the tooltip altogether. You must use "data-original-title" instead of just "title" because Bootstrap will automatically add it once you initialise the "title" attribute, and changing "title" to false will not remove the "data-original-title".

nikojpapa
  • 660
  • 1
  • 8
  • 16
0

Here's another working but not so elegant solution:

<span v-if="!!col.col_spec.tooltip" data-toggle="tooltip" >
    {{ col.col_spec.title }}
</span>
<span v-else >
    {{ col.col_spec.title }}
</span>
JJPandari
  • 3,454
  • 1
  • 17
  • 24