Reputation: 4599
I would like to wrap an element with a link ONLY if a link is available:
Normally I would use:
<a v-if="url" href="url">
<some-content></some-content>
</a>
<some-content v-else></some-content>
BUT this leads to a lot of code duplication, especially if some-content is complex.
I tried to use it like this:
<wrap-link :url="url">
<some-content></some-content>
</wrap-link>
Where wrap-link is like the following, but I can't get rid of the "span" in the v-else
part.
<template>
<a v-if="url" :href="url">
<slot></slot>
</a>
<span v-else>
<slot></slot>
</span>
</template>
<script>
export default {
props: {
url: { type: String, default: '' },
}
}
</script>
Any suggestions?
Upvotes: 1
Views: 431
Reputation: 138336
Vue 3 allows multiple root nodes, so putting the v-else
directive directly on the <slot>
in the root is allowed:
<template>
<a v-if="url" :href="url">
<slot></slot>
</a>
<slot v-else></slot>
</template>
In either version of Vue, you could use a <component>
whose properties are computed based on url
:
<template>
<component :is="component" v-bind="props">
<slot></slot>
</component>
</template>
<script>
export default {
props: {
url: { type: String, default: '' }
},
computed: {
component() {
return this.url ? 'a' : 'slot'
},
props() {
return this.url ? { href: this.url } : null
}
}
}
</script>
Upvotes: 3