最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuejs v-for on inline elements trims whitespace - Stack Overflow

programmeradmin4浏览0评论

When looping over an array (or object) with v-for on an inline element, vuejs does not render whitespace around said element.

For example, I have this html:

<div id="app">
    Vue Rendering<br>
    <a v-for="fruit in fruits" v-bind:href="fruit.url" v-html="fruit.label"></a>

    </div>
    <div>
    Navite rendering<br>
    <a href="apple.html">Apple</a>
    <a href="banana.html">Banana</a>
    <a href="peach.html">Peach</a>
</div>

and this javascript:

var fruits = [
    {
        label: 'Apple',
        url: 'apple.html'
    },
    {
        label: 'Banana',
        url: 'banana.html'
    },
    {
        label: 'Peach',
        url: 'peach.html'
    }
];

var app = new Vue({
    el: '#app',
    data: {
        fruits: fruits
    }
});

When Vue renders this, it deletes the spaces between the links. See this jsfiddle.

How can I counter this behaviour ?

When looping over an array (or object) with v-for on an inline element, vuejs does not render whitespace around said element.

For example, I have this html:

<div id="app">
    Vue Rendering<br>
    <a v-for="fruit in fruits" v-bind:href="fruit.url" v-html="fruit.label"></a>

    </div>
    <div>
    Navite rendering<br>
    <a href="apple.html">Apple</a>
    <a href="banana.html">Banana</a>
    <a href="peach.html">Peach</a>
</div>

and this javascript:

var fruits = [
    {
        label: 'Apple',
        url: 'apple.html'
    },
    {
        label: 'Banana',
        url: 'banana.html'
    },
    {
        label: 'Peach',
        url: 'peach.html'
    }
];

var app = new Vue({
    el: '#app',
    data: {
        fruits: fruits
    }
});

When Vue renders this, it deletes the spaces between the links. See this jsfiddle.

How can I counter this behaviour ?

Share Improve this question asked Jan 24, 2018 at 14:47 G2NG2N 1691 gold badge1 silver badge7 bronze badges 2
  • 5 The problem is when you iterate directly over the anchor, there's no whitespace to render. If you specfically want to render white space, you need to include it in the things to render like this jsfiddle.net/mq4hc614/2. This might, however, be better handled with CSS. – Bert Commented Jan 24, 2018 at 14:51
  • 1 It works fine this way, thank you. In case anyone reading this might not want an non breaking space (that's my case), you have to explicitly declare the white space with &#32; – G2N Commented Jan 24, 2018 at 15:36
Add a comment  | 

3 Answers 3

Reset to default 13

From the Docs on List Rendering > v-for on a <template>

Similar to template v-if, you can also use a <template> tag with v-for to render a block of multiple elements. For example:

<ul>
 <template v-for="item in items">
   <li>{{ item.msg }}</li>
   <li class="divider" role="presentation"></li>
 </template>
</ul>

So in order to get sibling elements (and yeah, a breaking space character &#32; would count as one), you'll have to add the loop to a parent <template> container and then include any elements / spacing you want in the looped contents like this:

<template v-for="fruit in fruits" >
  <span>{{fruit}}</span>&#32;
</template>

As of Vue 2.x+, templates trim any breaking space characters, even if they are escaped.

Instead, you can add a slot or text interpolation like this:

<template v-for="fruit in fruits" >
  <span>{{fruit}}</span><slot> </slot>
</template>
<template v-for="fruit in fruits" >
  <span>{{fruit}}</span>{{ ' ' }}
</template>

If you only want spaces in-between elements, you can output the space conditionally:

<template v-for="(fruit, i) in fruits" >
  <span>{{fruit}}</span>{{ i < fruits.length -1 ? ', ': '' }}
</template>

Demo in Stack Snippets

var app = new Vue({
    el: '#app',
    data: {
        fruits: ["apple", "banana", "carrot"]
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.0/vue.js"></script>

<div id="app">
    <template v-for="(fruit, i) in fruits" >
      <span>{{fruit}}</span>{{ i < fruits.length -1 ? ', ': '' }}
    </template>
</div>

Further Reading:
Issue #1841 - Suggestion: v-glue / v-for element joins

I had a case where I needed to wrap each character (including spaces) of a string in a <span> and solved it this way.

<template v-for="(letter, i) in 'My text with spaces'">
    <span v-if="letter !== ' '">{{ letter }}</span>
    <span v-else>&nbsp;</span>
</template>

You can use CSS:

<a v-for="fruit in fruits" v-bind:href="fruit.url" v-html="fruit.label" 
   style="margin-right: 5px;"></a>
发布评论

评论列表(0)

  1. 暂无评论