【问题标题】:VueJS: How to output a comma separated array?VueJS:如何输出逗号分隔的数组?
【发布时间】:2017-06-27 00:57:11
【问题描述】:

我知道在 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>

这可能吗?

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    您可以使用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>

    【讨论】:

    • 我很想知道为什么投反对票的人投反对票。因此我可以改进这个答案。并且知道下次如何做得更好。
    • 使用.length有什么问题?
    • 性能,它们可能会受到影响,因为.length 可能o(n) 复杂性。见this related question
    【解决方案2】:

    您可以使用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>

    【讨论】:

    • 你可以避免使用.length,方法是与0比较,并反转文本和命令的位置。见stackoverflow.com/a/42129590/6320039
    • 这其实是最好的答案,完美运行,谢谢!
    【解决方案3】:

    我最终做的是:

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

    在 CSS 中:

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

    【讨论】:

    • 这个解决方案非常优雅,但是断线行为很糟糕。当您调整浏览器大小时,逗号可以转到与最后一个单词隔离的段落的下一行。
    • 我做了非常相似的 .comma-list > li:not(:last-child)::after { content: ", " }
    • 不是一个好的解决方案,也往往会干扰屏幕阅读器,阻止浏览器正确处理文本(高级字体功能、换行符等)。不要在这些任务中滥用 CSS。
    • @PauloCheque,我想知道你为什么称它为 “优雅”。对我来说,因为它将逗号与元素分开,所以这是错误的。我相信这里的优雅 解决方案是.join(', ')。因为它使逗号坚持每个项目的最后一个字母,并且因为它不添加额外的逗号。这就是“优雅”
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

      使用“模板”的解决方案

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

      【讨论】:

        【解决方案6】:

        我的组件:

        <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>
        

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 这是一个很好的解决方案。我能够将它用于 1 级数组。我确实必须为对象数组找到另一种替代方法。
          • 正是我想要的,因为我需要它在 select
          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

            我可以建议使用 i > 0 作为检查吗?

            我已经包装了分隔符,以便 {{ ' ' }} 可以用于仅具有空格并避免 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>
            

            【讨论】:

              【解决方案10】:

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

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

              【讨论】:

              • 我相信这个答案是stackoverflow.com/a/50910693/6320039的副本。
              • 如果你需要在迭代过程中做其他事情,那么它就不起作用了,只适用于纯字符串。
              • @Karl Adler 在这种情况下,我会使用计算变量或方法并执行 list.map.join
              【解决方案11】:

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

              【讨论】:

                【解决方案12】:

                在不同的视图中,使用:after:before 带有逗号并不是一个好主意,因为在调整窗口大小时浏览器不将其作为字符串处理。

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

                为了克服这两个问题,我们可以将逗号括在一个单独的元素中,并使用 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;
                }
                

                【讨论】:

                  【解决方案13】:

                  如果您确实想要控制 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>
                  

                  【讨论】:

                    猜你喜欢
                    • 2023-03-20
                    • 2021-05-10
                    • 1970-01-01
                    • 2018-01-29
                    • 2011-07-14
                    • 2019-05-21
                    • 1970-01-01
                    • 2010-09-22
                    • 1970-01-01
                    相关资源
                    最近更新 更多