VueJS:如何输出逗号分隔的数组?

VueJS: How to output a comma separated array?

我知道在 VueJS 中我可以遍历数组:

<span v-for="(element, index) in list">{{ element }}</span>

但是如果我想要一个以逗号分隔的列表怎么办?例如,如果 list = ["alice", "bob", "chuck"],那么上面会输出:

<span>alice</span><span>bob</span><span>chuck</span>

不过,我想要的是:

<span>alice</span>, <span>bob</span>, <span>chuck</span>

这可能吗?

您可以在第一个参数上使用带有条件的 v-if 属性来做到这一点,避免使用 .length:

var app = new Vue({
  el: '#app',
  data: {
    list: ['john', 'fred', 'harry']
  }
})
<script src="https://vuejs.org/js/vue.min.js"></script><div id="app">
  <span v-for="(element, index) in list">
    <span v-if="index != 0">, </span><span>{{ element }}</span>
  </span>
</div>

您可以使用 conditional rendering 隐藏最后一个 ,,如下所示:

var demo = new Vue({
  el: '#demo',
  data: function() {
    return {
      lists: ['Vue', 'Angular', 'React']
    };
  }
})
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="demo">
  <span v-for="(list, index) in lists">
    <span>{{list}}</span><span v-if="index+1 < lists.length">, </span>
  </span>
</div>

我最后做的是:

<span v-for="element in list" class="item">
  <span>{{ element }}</span>
</span>

在CSS中:

.item + .item:before {
  content: ", ";
}

如果你想用 JS 的方式来做,你可以只做一个计算 属性;你甚至可以继续 span 方法。

computed {
  listCommaSeparated () { return this.list.join(', '); },
  listCommaSpans () { return '<span>' + this.list.join('</span><span>') + '</span>'; },
},

从渲染性能的角度来看,这绝对是首选方式。

解决方案使用"template"

 <template v-for="(element, index) in list">
   <span>{{element}}</span><template v-if="index + 1 < list.length">, </template>
 </template>

我的组件:

<template>
<ul v-if="model.length">
    <li v-for="item in model">{{item}}</li>
</ul>
</template>
<style scoped>
ul {
    list-style: none;
}
li {
    display: inline-block;
}
li:not(:last-child)::after {
    content: ", ";
}
</style>
<script>
export default {
    props: ['model']
};
</script>

如果您只关心逗号分隔,请使用 Javascript 的内置 join 方法:

{{ list.join(', ') }}

只需添加另一个我更喜欢使用的替代方案:

<span v-for="(item, index) in list">
    {{ item }}{{ (index+1 < list.length) ? ', ' : '' }}
</span>

我可以建议使用 i > 0 作为校验吗?

我已经包装了分隔符,这样 {{ ' ' }} 就可以用于 space 并避免 span 被视为空。

<span
    v-for="(item, i) in list"
    :key="i">
   <span v-if="i>0">{{ ', ' }}</span>
   <span class="text-nowrap">{{ item }}</span>
</span>

<span
    v-for="(item, i) in list"
    :key="i">
   <!-- if not wrapped in a span will leave a space before the comma -->
   <span>{{ (i > 0 ? ', ' : '') }}</span>
   <span class="text-nowrap">{{ item }}</span>
</span>

最好使用内置 JS Array.join 这样的方法

<span>{{ list.join(', ') }}</span>

可能的样本
<span v-for="(item,i) in items"> {{(item !='' && i !=0) ? ',' : ''}} {{item.title}} </span>

有不同的观点认为使用 :after:before 有逗号不是一个好主意,因为浏览器在调整 window 大小时不将其作为字符串处理.

如果我们尝试在每次迭代中使用条件运算符来检查它是第一个还是最后一个元素,如果我们有大量项目,这将是一个开销。每当我们进行更改检测时,也会重新评估条件。

为了克服这两个问题,我们可以将逗号括在一个单独的元素中并使用 CSS :last-child 选择器将其隐藏为

<template v-for="item in list">
    <span class="item">
        {{item}}
        <span class="comma">
            ,
        </span>
    </span>
</template>

并在 CSS

.item:last-child .comma {
    display: none;
}

如果您确实想控制 dom 的外观(例如,实际上想要实现您询问的 dom 结构),您可以像这样创建一个 functional component

<script>
// RenderList.vue
export default {
  functional: true,
  render(createElement, context) {
    // Read the list of entries by accessing the prop "list"
    const listEntries = context.props.list;

    // Return a custom list of elements for each list entry.
    // Only return a `,` if it's not the last entry.
    return listEntries.map((listElement, idx) => {
      return [
        createElement("span", listElement),
        idx < listEntries.length - 1 ? ", " : "",
      ];
    });
  },
};
</script>

您可以像这样使用这个组件:

<template>
  <RenderList :list="['alice', 'bob', 'chuck']" />
</template>