I am fairly new to Vue, so if what I am doing is absurd, please let me know.
A common convention in many of my components is something like this (only showing relevant parts of code):
thing = {text:"some text", href: "https://a.link"} <template> <div> <a v-if="thing.href" :href="thing.href">{{thing.text}}</a> <span v-else>{{thing.text}}</span> </div> </template>
I dislike this as thing.text
may in actuality be a lot of stuff (not just text).
Further, I dislike the redundancy for rendering the anchor tag i.e. if there is an href
be an anchor tag with an href
.
Thus I would like to shorten and clean this up like so:
<template> <div> <div :is="complexThing.href ? 'a' : 'span'" :href="complexThing.href">{{complexThing.lotsOfStuff}}</div> </div> </template>
Which is nice, we are down to one line, but at the cost of href
being bound to nothing when it doesn’t exist…
So is there a way to conditionally bind a prop?
Of course I could wrap this convention into a component of its own. However, I find that what it is, is very dependent on the component I am using it in. I do not like having to copy and paste a chunk of identical code between an if-else statement just to get an href.
Thoughts? Ideas?
e.g.
<template> <div :is="href ? 'a' : or" :href="href"> <!-- href=(unknown) will show in inspector if href is undefined --> <slot></slot> </div> </template> <script> export default { name: 'AnchorOr', props: ['or', 'href'] } </script> <style> </style>
which can then be used like:
<AnchorOr class="inline-text" :or="span">{{text}}</AnchorOr> <AnchorOr class="linked-module" :or="div">{{component}}</AnchorOr>
Advertisement
Answer
In your small example, I would leave it as-is; however if {{ thing.text }}
were instead a larger template partial then duplicating it is a no-no.
You would normally use <component>
for situations like this:
<component v-bind="thingProps">{{ thing.text }}</component>
computed: { thingProps() { return this.thing.href ? { is: 'a', href: this.thing.href } : { is: 'span' }; } }