I have a set of elements being generated in a v-for directive that, if the object has a url property, get wrapped in an <a> tag - otherwise, I need it to just emit the element itself.
For example,
var data = {
    events: [
        {name: "Foo"},
        {name: "Bar", url: "google.com"}
    ]
};
and the corresponding HTML:
<div v-for="event in events">
    <span>{{event.name}}</span>
</div>
What I need is to wrap the <span> in an <a v-bind:href="url"> only if there is a url property present.
I understand I could use a v-if and use two spans, such as:
<span v-if="!event.url">{{event.name}}</span>
<a v-bind:href="event.url" v-if="event.url">
    <span>{{event.name}}</span>
</a>
However, in my use case the <span> element here could be massive and I don't want to repeat myself just to wrap the element.
Is there a way to achieve a conditional wrap such as the above?
The v-if directive is a Vue. js directive used to toggle the display CSS property of a element with a condition. If the condition is true it will make it visible else it will make it invisible. First, we will create a div element with id as app and let's apply the v-if directive to this element with data.
To only show slot if it has content with Vue. js, we can check the this. $slots property in our component. to check if the footer slot is added with !!
v-if. The directive v-if is used to conditionally render a block. The block will only be rendered if the directive's expression returns a truthy value.
If v-if == true and v-show changes from true to false , the leave transition occurs as expected. If v-show== true and v-if changes from true to false , the element is immediately removed, no transition occurs. My use case for this is using both v-if and v-show around media ( img , video ).
You can use v-html for example and render your logic inside a function: 
function wrapSpan(el, link) { // link wrapper function
  return `<a href="${link}">${el}</a>`;
}
new Vue({
  el: '#app',
  data: {
    events: [
      {name: "Foo"},
      {name: "Bar", url: "google.com"}
    ]
  },
  methods: {
    element: function(i) {
      const name = this.events[i].name;
      const url = this.events[i].url || null;
      const span = `<span style="color: green">${name}</span>`; // long span
      return (url) ? wrapSpan(span, url) : span;
    }
  }
});<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
  <div v-for="(event, index) in events">
    <span v-html="element(index)"></span>
  </div>
</div>If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With