When v-for
lists are rendered, they do so without any space between elements.
For example:
<ol class="breadcrumb">
<li v-for="n in 3"><a>Crumb {{ n+1 }}</a></li>
</ol>
renders as:
<ol class="breadcrumb">
<li><a>Crumb 1</a></li><li><a>Crumb 2</a></li><li><a>Crumb 3</a></li>
</ol>
Because of this, and due to a known issue in Bootstrap, the above breadcrumb's separator spacing will display incorrectly (note the spacing on the left of a separator is smaller than on the right):
To work around this (_I'm writing a breadcrumb component_), I run the v-for
loop in a <template>
wrapper so I can append a <slot>
containing a blank space after each <li>
element, like so:
<ol class="breadcrumb">
<template v-for="n in 3">
<li><a>Crumb {{ n+1 }}</a></li>
<slot> </slot>
</template>
</ol>
which renders as:
<ol class="breadcrumb">
<li><a>Crumb 1</a></li>
<li><a>Crumb 2</a></li>
<li><a>Crumb 3</a></li>
</ol>
and corrects the separator spacing problem.
To avoid such a workaround, I was wondering if there's any interest in the idea of a v-glue
directive for v-for
loops, as a way to pass an expression/value to the loop to be used as the glue that joins each item of the loop together?
For example, the problem above could be negated by simply passing v-glue=" "
like so:
<ol class="breadcrumb">
<li v-for="n in 3" v-glue=" ">Crumb {{ n+1 }}</li>
</ol>
which would render as (note the spaces between the <li>
tags):
<ol class="breadcrumb">
<li><a>Crumb 1</a></li> <li><a>Crumb 2</a></li> <li><a>Crumb 3</a></li>
</ol>
I can imagine other creative applications of such a feature, e.g. dividers between panels, etc.
Interested to hear your thoughts!
in regard to #1842 i think this wont be needed and could be replaced with
<ol class="breadcrumb">
<template v-for="n in 3">
<li><a>Crumb {{ n+1 }}</a></li>
{{$last?'':' '}}
</template>
</ol>
Although I can see where you are coming from, I don't think an edge case like this justifies a special directive in Vue.js core, especially when it is caused by a bug in another library...
@vprimachenko Thanks for the reply.
@yyx990803 Gotcha. Cheers.
It's also annoying when v-for
generates html like this:
<span>tag 1</span><span>tag 2</span><span>tag 3</span>...
When the tag list gets long it won't linebreak at all.
Sometimes developers forget, there's more to writing html than just what's inside the tags.
I'm suffering from this now as well. This is actually a bug. it must render a space between tags.
<span class="tag is-info" v-for="(filter, index) in filters">
{{ filter.text }}
<button class="delete is-small"></button>
</span>
All tags are rendered with no spacing.
You could put the html of an entire website on one line and it should still work, doubt this is a bug as it's generated html. Jade/Pug does the same thing. As long as your source looks proper it shouldn't matter what the generated html looks like (As long as it's valid html).
You could put the html of an entire website on one line and it should still work, doubt this is a bug as it's generated html.
Spaces between tags are legitimately different HTML though this is really only a problem with inline elements like both reporters are using because that's the only time it really affects layout. https://jsfiddle.net/tqzwh62d/1/
In my experience it is generally the problem that developers need to _remove_ space between tags to stop browsers from affecting layout because you want to control the spacing very specifically with CSS so the current behavior is definitely the sane choice. I can see where there are times where you might want to trigger that behavior.
I do wonder if you could work around it with a
#component span:after{ content: " "; }
though.
A simple workaround would be to use
<template v-for="n in 3">
<span :key="n">iteration {{n}}</span>
{{ ' ' }}
</template>
Adding a space between elements is not directly possible, but you can move the v-for
to a parent <template/>
, which results in the expected outcome. You could also replace the space with a non-breaking space (
).
Here are 5 different approaches for those out there looking for a v-join
or v-glue
or $last
or v-trim
. And also explanations of what those other 4 things would be if added to Vue's API.
Most helpful comment
A simple workaround would be to use
Adding a space between elements is not directly possible, but you can move the
v-for
to a parent<template/>
, which results in the expected outcome. You could also replace the space with a non-breaking space (
).