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